假设我在同一页上有以下元素:
我想实现以下逻辑:
/appliedOptionA/appliedOptionB)第一个想法:配置ng-路由器,获取过滤器数据作为param,将数据转换为模型,构造过滤器面板,加载项目,构造项目面板。主要问题:当用户更改筛选器时,它应该如何工作?如果我要更新URL,它将触发相同的控制器与不同的param,并重复过程->获取过滤器数据作为param,将数据转换为模型,构造过滤器面板,项目等。我不需要它-我的模型和UI已经是最新的。
我的问题是:
保持模型和URL同步的正确方法是什么?URL (ng-route)还是模型更改管理URL (如何?)
发布于 2014-12-07 21:41:08
我的建议是使用角用户界面路由器而不是ng-router,因为angular-ui-router提供了更多的灵活性,而且在我看来更容易使用。
考虑到您的“主要问题”,听起来您希望有一个应用程序控制器(我们将其称为"appCtrl")来处理所有更改并对其模型进行必要的更改。这种方法的主要缺点是它迫使您在appCtrl中维护“appCtrl”模型,这并不有趣,可能会导致不必要的头痛。一种更简单的方法是让另一个控制器来处理对url的这些更改,而不是appCtrl本身。话虽如此,让我向你展示你是如何做到这一点的。
*警告:帖子很长!(但希望能有所帮助) *
正因为如此,我还创建了一个演示,展示了我将要讨论的一切,以防您“只想要teh codez":
创建应用程序
既然我们正在创建一个全新的应用程序,那么让我们从创建和配置应用程序开始。
注意:请记住将angular-ui-router脚本加载到应用程序中,并添加依赖项。
app.js
var myApp = angular.module('myApp', ["ui.router"]);现在我们有了app,让我们使用ngApp指令将其添加到index.html中。
index.html
<body ng-app="myApp"></body>在应用程序就位之后,让我们看看您在问题中处理的问题:
您想要做的是创建一个状态。本质上,状态是基于url模式激活/停用的。给定特定的模式,您可以告诉应用程序如何操作(使用控制器)和外观(使用模板)。在继续之前,请确保引用url路由,这将有助于使用url模式。
我们需要:
"filteredItems")让我们配置应用程序,以及:
home状态filteredItems状态app.js
myApp.config(function($stateProvider, $urlRouterProvider){
// default url - used if url pattern is not recognized
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', { // default state
url: '/'
})
.state('filteredItems', { // give the state a name
url: "/:appliedOptionA/:appliedOptionB", // provide the url pattern
controller: 'FilteredItemsCtrl', // controller to use for this state
templateUrl: "filteredItems.html" // url for the template
});
});我们现在已经将状态的url配置为接受参数(appliedOptionA和appliedOptionB)。使用$stateParams service,我们可以创建一个filteredItemsCtrl,并让它负责过滤掉数据。
但在我们这么做之前,我们应该创造一个服务。在使用角时,避免使用使用控制器来维护数据,因为它们可以创建/销毁。最佳实践是使用服务。话虽如此,让我们创建一个惊人的itemService
itemService.js
angular.module('myApp').factory('itemService', itemService);
function itemService (){
var items = {
appliedOptionA: [ 'Item 1', 'Item 2', 'Item 3' ],
appliedOptionB: [ 'Item 4', 'Item 5', 'Item 6' ]
};
function getItems (){
return items;
}
return {
getItems: getItems
}
}很漂亮对吧?我很高兴你也这么想!
现在我们有了一个服务,我们可以创建FilteredItemsCtrl了。让我们还将新创建的itemService注入到FilteredItemsCtrl中,以便它能够访问数据。
注意:请记住将$stateParams服务作为依赖项注入!
filteredItemsCtrl.js
angular.module('myApp').controller('FilteredItemsCtrl', filteredItemsCtrl);
filteredItemsCtrl.$inject = ['$stateParams', '$scope', 'itemService'];
function filteredItemsCtrl ($stateParams, $scope, itemService){
var items = itemService.getItems(); // get items from service
// filter items
$scope.appliedOptionA = items.appliedOptionA.filter(function (item){
if ($stateParams.appliedOptionA){
return item.toLowerCase().indexOf($stateParams.appliedOptionA) > -1 ||
item.indexOf($stateParams.appliedOptionA) > -1
}
});
$scope.appliedOptionB = items.appliedOptionB.filter(function (item){
if ($stateParams.appliedOptionB){
return item.toLowerCase().indexOf($stateParams.appliedOptionB) > -1 ||
item.indexOf($stateParams.appliedOptionB) > -1
}
});
}当我们定义状态的url时,我们将其设置为:url: "/:appliedOptionA/:appliedOptionB"。这意味着$stateParams将使用appliedOptionA、appliedOptionB属性填充。这也意味着每次URL更改时,都会创建一个新的 filteredItemsCtrl,因此,您不必维护应用程序的模型!
在我们忘记之前,我们还需要为这个状态创建一个模板。
filteredItems.html
<div>
<div>
<span>Filtered Option A Items:</span>
<ul>
<li ng-repeat="optionItemA in appliedOptionA">
{{ optionItemA }}
</li>
</ul>
</div>
<div>
<span>Filtered Option B Items:</span>
<ul>
<li ng-repeat="optionItemB in appliedOptionB">
{{ optionItemB }}
</li>
</ul>
</div>
</div>创建了状态、filteredItemCtrl和视图之后,剩下的就是包含ui-view指令,以便状态模板正确显示:
index.html
<body ng-app="myApp"
ng-controller="MyAppCtrl">
<div>
<div>
Applied Option A: <input ng-model="appliedOptionA" />
</div>
<div>
Applied Option B: <input ng-model="appliedOptionB" />
</div>
<button type="button"
ng-click="filter()">Search</button>
</div>
<!-- where the state template goes -->
<div ui-view></div>
</body>这就是一切!很抱歉,很长的帖子,但希望你找到了这方面的信息!如果你有任何问题,请告诉我!
发布于 2014-12-07 19:05:22
当您希望搜索关键字在URL中得到反映(以便它们可以被书签和直接寻址)时,我建议不要强制对模型进行每次更改(在每次击键之后),而是等待表单的提交。然后重写URL (通过$location.path和/或$location.search),ngRoute就会启动。
NgRoute将(重新)加载/刷新页面,就像它是第一次一样,这与包含搜索关键字的可直接寻址页面的想法相匹配。我不建议在收到提交时立即获取数据,因为正如您所说的,ngRoute将刷新页面。
https://stackoverflow.com/questions/27345683
复制相似问题