5

我的index.html模板中有一个搜索栏,我需要在某些页面上隐藏它。我正在使用ui-router$state

我可以完成这项工作的唯一方法是注入$rootscope我所有的控制器,或者在需要的地方打开ng-hide: truefalse关闭它们。(我真的只需要隐藏在 1 或 2 页上)

我认为这不是正确的方法,因为我所有的控制器现在都依赖并注入到$rootscope.

还有另一种方法可以做到这一点吗?

4

6 回答 6

3

GlobalCtrl让我们从一个添加到bodyorhtml标签的全局控制器示例开始,例如ng-controller="GlobalCtrl.

这样做将使我们能够GlobalCtrl在您的单页 Angular 应用程序(当您使用ui-router)中保持此范围,并且我们可以避免使用$rootScope(实际上模仿使用$rootScope)。

现在,在你的GlobalCtrl定义中是这样的:

// Using an object to avoid the scope inheritance problem of Angular
// https://github.com/angular/angular.js/wiki/Understanding-Scopes
$scope.globalData = {showSearchBar: true};

// This callback will be called everytime you change a page using ui-router state
$scope.$on('$stateChangeStart', function(event, toState, toParams) {
    $scope.globalData.showSearchBar = true;

    // Just check for your page where you do not want to display the search bar
    // I'm using just an example like I don't want to display in contac-us page named state
    if (toState.name == 'contact-us' || toParams.foo == "bar") {
        $scope.globalData.showSearchBar = false;
    }
});

现在,在您的 中index.html,只需使用ng-show

<div ng-show="globalData.showSearchBar">
    <input type="text" ng-model="query" />
</div>
于 2015-12-10T14:13:54.653 回答
1

您可以使用$rootin 表达式从模板访问 $rootScope。喜欢:

<div ng-show="$root.appSettings.flag">
    <span>Hello!</span>
</div>
于 2015-12-10T17:22:02.817 回答
0

我不喜欢继续使用控制器,我认为最好以不依赖于另一个控制器的方式分离应用程序的每个部分。

我将使用服务来共享数据:

'use strict';

angular.module('yourModule')
    /**
        A service used to share resources between controllers
    */
    .factory('Shared', [function () {
        var resources = {};

        resources.targetList = [];
        resources.isVisibleDivA = true;
        resources.isVisibleDivB = false;

        return resources;
    }]);

通过这种方式,注入服务您将始终能够与正确格式化布局所需的状态变量进行交互。

如果你想重用一个控制器,你只需要添加一个模拟服务,你就不需要依赖控制器。

于 2015-12-10T14:19:25.000 回答
0

ui-router您可以使用抽象状态来创建层次结构。通过这种方式,您可以拥有一个具有搜索栏视图的父路由,而另一个则没有。你所有的实际路线都可以从这两个继承,你就完成了。

像这样的东西

$stateProvider
.state('rootLayout', {
    abstract: true,
    // Note: abstract still needs a ui-view for its children to populate.
    // You can simply add it inline here.
    template: '<div><div ui-view="topbar"></div><div ui-view></div></div>'
})
.state('searchbarLayout', {
    abstract: true,
    views: {
        '@rootLayout': { 
             // Note: abstract still needs a ui-view for its children to populate.
             // You can simply add it inline here.
             template: '<div ui-view></div>'
        },
        'topbar@rootLayout': { 
             template: '<input type="search" />'
        },
    }    
});
于 2015-12-10T15:26:26.287 回答
0

例如

<div ng-controller="SearchCtrl">
<div ng-if="show">
...
</div>
</div>

app.controller('SearchCtrl', ['$state', '$scope', function($state, $scope) {
    $scope.show = !$state.is('someState1') && !$state.is('someState2');
}

这不是很好的风格,但会很有效。

于 2015-12-10T13:52:40.533 回答
0

我在应用程序的运行功能中注册了对象

.run([ '$rootScope', function ($rootScope) {
  $rootScope.searchBar = { value: true };
}])

然后使用范围更改值。这会停止将 $rootscope 添加到每个控制器中

$scope.searchBar.value = false;

在 index.html 页面中设置值

<div ng-show="searchBar.value" ng-include src="'app/shared/search.html'"></div>
于 2015-12-15T13:25:15.337 回答