我的建议是使用angular-ui-router 并使用它而不是ng-router,因为angular-ui-router 为您提供了更大的灵活性,并且在我看来更易于使用。
鉴于您的“主要问题”,听起来您希望有一个应用程序控制器(我们将其称为"appCtrl")处理所有更改并对其模型进行必要的更改。这种方法的主要缺点是它迫使您在appCtrl 中维护“filteredItems”模型,这并不有趣,并且可能导致不必要的麻烦。一种更简单的方法是让另一个控制器处理对 url 的这些更改,而不是 appCtrl 本身。话虽如此,让我向您展示如何做到这一点。
*警告:帖子很长! (但希望有帮助)*
因此,我还创建了一个我将要讨论的所有内容的演示,以防你“只想要 codez”:
创建应用程序
由于我们正在创建一个全新的应用程序,让我们从创建和配置应用程序开始。
注意:请记住将angular-ui-router 脚本加载到您的应用程序中并添加依赖项。
app.js
var myApp = angular.module('myApp', ["ui.router"]);
现在我们有了app,让我们使用ngApp directive 将它添加到index.html。
index.html
<body ng-app="myApp"></body>
应用到位后,让我们看看您在问题中解决的问题:
- URL 应在路径 (/appliedOptionA/appliedOptionB) 中包含应用的过滤器数据
- 当用户打开站点应用时,从 URL 获取过滤器数据,更新过滤器面板和项目面板
- 当用户更改过滤器应用更新 URL 并刷新项目时
您要做的是创建一个state。本质上,状态是根据 url 模式激活/停用的。给定一个特定的模式,您可以告诉应用程序如何操作(使用控制器)和外观(使用模板)。在继续之前,请确保引用 url routing,这将有助于 url 模式。
我们需要:
- 为状态命名 (
"filteredItems")
- 提供网址格式
- 提供控制器
- 提供templateUrl
让我们配置应用程序,以及:
- 在url不存在的情况下提供默认url路由
- 添加默认
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,并让它负责过滤掉数据。
但在我们这样做之前,我们应该创建一个服务。使用 Angular 时,避免使用控制器来维护数据,因为它们可以被创建/销毁。最佳实践是改用服务。话虽如此,让我们创建一个惊人的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 将填充应用选项A、应用选项B 属性。这也意味着每次 URL 更改时,都会创建一个 new 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>
这就是它的全部内容!很抱歉这篇文章很长,但希望你能发现这个信息!如果您有任何问题,请告诉我!