【问题标题】:AngularJS: What is the best way to bind a directive value to a service value changed via a controller?AngularJS:将指令值绑定到通过控制器更改的服务值的最佳方法是什么?
【发布时间】:2014-03-28 11:31:30
【问题描述】:

我想创建一个“标题”服务来处理它的标题、按钮和颜色。
主要思想是能够在我的控制器中用一行来自定义这个标题,如下所示:

function HomeCtrl($scope, Header) {
    Header.config('Header title', 'red', {'left': 'backBtn', 'right': 'menuBtn'});
}

所以我创建了一个服务(现在我只关注标题):

app.service('Header', function() {
    this.config = function(title, color, buttons) {
        this.title = title;
    }
});

...还有一个指令:

app.directive('header', ['Header', function(Header) {
    return {
        restrict: 'E',
        replace: true,
        template: '<div class="header">{{title}}</div>',
        controller: function($scope, $element, $attrs) {
            $scope.$watch(function() { return Header.title }, function() {
                $scope.title = Header.title;
            });
        }
    };
}]);

所以,这确实有效,但我想知道是否没有更好的方法。 尤其是 Header.title 属性上的 $watch。对我来说似乎不是很干净。

关于如何优化这个的任何想法?

编辑:我的标题不在我的视野中。所以我不能直接从我的控制器更改 $scope 值。

Edit2:这是我的一些标记

<div class="app-container">
    <header></header>

    <div class="content" ng-view></div>

    <footer></footer>
</div>

(不确定这段 html 是否会有所帮助,但我不知道哪个部分实际上会......)

谢谢。

【问题讨论】:

    标签: angularjs service binding directive


    【解决方案1】:

    如果您在视图中使用标题,为什么要使用范围来保存对象,而不是服务?这样你就不需要指令来更新 scope.header,因为如果这个对象发生变化,绑定会更新它

       function HomeCtrl($scope, Header) {
         $scope.header = Header.config('Header title', 'red', {'left': 'backBtn', 'right': 'menuBtn'});
        }
    

    并将标题称为

    <h1>{{header.title}}</h1>
    

    更新

    把这个放在一个控制器中,封装标签绑定到头部:

    $scope.$on("$routeChangeSuccess", function($currentRoute, $previousRoute) {
        //assume you can set this based on your $routeParams
        $scope.header = Header.config($routeParams);
    });
    

    【讨论】:

    • 因为标题不在我的 ng-view 中。
    • 不一定是..你也可以发布你的标记吗?
    • 嗯,它是一个移动应用程序。页眉和页脚不在我的视野范围内,所以我不需要用它“污染”我的模板。我想这不太灵活,但更干燥。
    • 对不起,我误解了你的评论。我会用一些标记更新我的帖子。
    【解决方案2】:

    简单的解决方案可能只是添加到 rootScope。我总是使用每个控制器都需要的一些真正的全局变量来做到这一点,主要是用户登录数据等。

    app.run(function($rootScope){
        $rootScope.appData={
                "header" :  {"title" : "foo"}, 
                "user" :{}
        };
    });
    

    .. 然后根据需要将 $rootScope 注入您的控制器。

    【讨论】:

    • 实际上这是我在寻找更清洁的解决方案之前所做的:) 我不确定这是最佳实践(使用 $rootScope)。另外,我希望能够在我的控制器中的一行中配置我的标题,所以我保持简短。专门的服务似乎是个好主意。
    • 来自 AngularJS 常见问题解答:有时您希望将某些数据片段对整个应用程序进行全局化。对于这些,您可以像任何其他范围一样注入 $rootScope 并在其上设置值。由于作用域从根作用域继承,这些值将可用于附加到指令(如 ng-show)的表达式,就像本地 $scope 上的值一样。 docs.angularjs.org/misc/faq
    • 还有来自 Angular 常见问题解答......“相反,不要创建一个生活中唯一目的是存储和返回数据位的服务”
    • 该死,这正是我正在做的事情(使用服务只返回数据位)...如果我不想拥有 3 或 4 个 $rootScope,还有其他解决方案吗? myvar = myvalue 在我的每个控制器中?
    • 可能使用事件在你的控制器之间发送消息? (尽管我认为您使用 $rootScope 的原始方法是一个不错的方法) $rootScope.$broadcast("headerConfigRequest",{...});并让您的标头 Controller ... .$on("headerConfigRequest", function...)
    猜你喜欢
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-12
    • 2013-04-19
    相关资源
    最近更新 更多