【问题标题】:How to update directives based on service changes?如何根据服务更改更新指令?
【发布时间】:2015-04-01 11:02:12
【问题描述】:

我有一个包含滑块(mySlider)的指令(parent-directive),在stop 事件中,调用带有2 个参数的角度$resource 服务,并且该服务返回一个对象。 指令结构:

<parent-directive>
<div ui-slider="slider.options" ng-model="mySlider" id="my-slider">
<span child-directive-one></span>
<span child-directive-two></span>
<span child-directive-three></span>
<div>
    <span child-directive-four></child-directive-four>
</div>
</parent-directive

每当用户拖动滑块时,都会使用不同的参数调用服务并检索新结果,基于它我需要更新子指令。

我想到了三种方法:

  1. 对所有子元素使用 ng-model 而不是指令,将它们绑定到 parent-directive 中的控制器范围内;
  2. 第二个,我不知道该怎么做,是在parent-directive 中创建一个控制器,用于从服务发送和接收数据并将其共享给child-directives 以更新它们。
  3. 最后一个是在服务中创建一个状态变量,并使用类似于第 1 点的控制器更新它。(见上文)并使用 $watch 来监督变量状态,当它发生变化时更新 @ 987654329@.

我应该如何进行?

请在此处查看简短代码: http://jsfiddle.net/v5xL0dg9/2/

谢谢!

【问题讨论】:

    标签: javascript angularjs angular-services angular-directive


    【解决方案1】:
    1. ngModel 用于双向绑定,即允许用户干预值的控件。从描述来看,它们似乎是仅显示组件。所以我建议不要使用ngModel。

    2. 通常子指令需要其父指令。这允许他们调用父控制器上的方法。您需要的恰恰相反:父控制器需要调用子控制器的方法。可以做到:children调用一个registerChild()方法,parent在需要调用的时候遍历所有注册的children。我觉得这个实现很麻烦。

    3. 服务是全局/单例。我会投票反对将服务实现与 UI 需求联系起来。

    我的建议看起来像您对选项 3 的实现,但父控制器持有数据:

    1) 将要与子指令共享的数据放在父控制器的成员变量中:

    myApp.directive('parentDirective', ['myService', function(myService){
        ...
        controller: function($scope) {
            ...
            this.sharedThing = ...;
        }
    }]);
    

    sharedThing 可以在服务返回新数据时更新,或在任何其他需要时更新。

    2) 让孩子需要父母(就像您的选项 2),并观看此属性:

    myApp.directive('childDirectiveOne', function() {
        return {
            ...
            require: 'parentDirective',
            link: function(scope, elem, attrs, parentDirective) {
                scope.$watch(
                    function() {
                        return parentDirective.sharedThing;
                    },
                    function(newval) {
                        // do something with the new value; most probably
                        // you want to place it in the scope
                    }
                });
            }
        };
    });
    

    根据数据的性质,可能需要深入观察。

    【讨论】:

    • 。我按照您的建议实现了它,但我有 6 个子指令,这意味着 6 个 $watch 方法(该服务返回一个具有 6 个属性的 obj,我在 6 个子项中一一使用它们-指令)。为了获得更好的性能,我应该在 ctrl 上设置一个状态变量和一个对象变量以与指令共享它吗?在指令中要求只观察状态变量?但我认为这行不通。你怎么看?这是根据您的建议制作的代码:jsfiddle.net/8hkxv85x/1
    • 这个块是不是重复了几十次?如果不是这样,一些额外的手表应该不会影响性能。如果实际逻辑与小提琴的逻辑一样简单,那么我还将考虑使子指令具有隔离范围,在 '=' 属性中传递数据并将模板绑定到该范围属性(它还创建一个手表在引擎盖下)。
    • 谢谢你的回答,为什么我要让子指令具有独立的作用域,在“=”属性中传递数据?我在角度方面真的很新,我了解到只有当你想从指令中的父 DOM 获取东西时才会这样做。再次感谢! :)
    • 隔离作用域是一种将数据传递给指令的正式方式,它不依赖于特定的父作用域。
    • 谢谢,但我看不出我应该如何使用“=”,也许像 scope : {} 这样的空对象就足够了。如果我使用“=”,则意味着在 DOM 中添加一个属性。我觉得我很傻,我听不懂(只有今天有 12 小时的角,它挡住了我的思维 :))谢谢!
    猜你喜欢
    • 2014-12-09
    • 2021-10-22
    • 2016-01-07
    • 1970-01-01
    • 2018-12-28
    • 2017-10-20
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    相关资源
    最近更新 更多