简体   繁体   English

AngularJS:在不同的控制器之间共享数据

[英]AngularJS: Share data between different controllers

I have the following structures 我有以下结构

<div ng-controller='ctrlA'>
  <button ng-click='updateFactoryData(data)'></button>

  <custom-dir>Custom directive with ctrlB</custom-dir>
  <custom-dir>Custom directive with ctrlB</custom-dir>
  <custom-dir>Custom directive with ctrlB</custom-dir>
  ...
  <other-custom-dir>Custom directive with ctrlC</other-custom-dir>
  <other-custom-dir>Custom directive with ctrlC</other-custom-dir>
  <other-custom-dir>Custom directive with ctrlC</other-custom-dir>
  ...
</div>

I have a dataFactory, which when user clicks the button, the updated data will store in dataFactory, the dataFactory is injected to both ctrlB and ctrlC. 我有一个dataFactory,当用户单击按钮时,更新的数据将存储在dataFactory中,该dataFactory注入到ctrlB和ctrlC中。

The problem is, when data is updated after clicking the button, the changes do not reflect on both custom-dir and other-custom-dir, is there any way ctrlB and ctrlC's scope value automatically reflect the changes made in scope under ctrlA? 问题是,单击按钮后更新数据时,更改不会同时反映在custom-dir和other-custom-dir上,ctrlB和ctrlC的作用域值是否可以自动反映ctrlA下作用域的更改?

Thanks very much for the help! 非常感谢您的帮助!

Thanks all for the kind help!! 谢谢大家的帮助! I finally figure out why the change cannot be reflected, I watch the object parameter to see if there are changes, but watch only monitor the object reference instead of the actual content, after deep watching the object parameter, I can finally get the watch work! 我终于弄清楚了为什么更改不能反映出来,我观察对象参数看是否有变化,但是只观察监视对象引用而不是实际内容,深入观察对象参数后,我终于可以完成观察工作了! Thanks for all the help 谢谢你的帮助

<custom-dir para="{data: data}"></custom-dir>

Then in directive's link function 然后在指令的链接函数中

scope.$watch('para.data', function(n,o){
                alert('changed')
            }, true); //>> The true is important!!
  • Pass the value to attribute in the <custom-dir> and <other-custom-dir> 将值传递给<custom-dir><other-custom-dir>属性

    <custom-dir data="data"> </custom-dir> <custom-dir data="data"> </custom-dir>

  • Observe the change from the directive 观察指令中的更改

     attrs.$observe('data', function(value){ // call your directive controller here ... }) 

The Benefit : 好处:

By passing data from attribute, the directive do not have to know about the controller/the source of the data, so, this reduce dependecy. 通过从属性传递数据,指令不必知道控制器/数据源,因此,这减少了依赖性。

需要共享作用域的事实有点奇怪,因为您知道有一个可以包含$ scope项的父控制器

It's considered a best practice to use "controllerAs" and no longer use $scope . 使用“ controllerAs”并且不再使用$scope被认为是最佳实践。

By writing: 通过写:

<div ng-controller='ctrlA as a'>
    <button ng-click='a.updateFactoryData(data)'></button>
    <!-- ... -->
</div>

and: 和:

function ctrlA () {
    this.data = [];
    this.updateFactoryData = function (data) {
        //...
    }
}

You access your controller's data with a.data everywhere inside your div . 您可以在div任何位置使用a.data访问控制器的数据。

Basically what you require is here is share the factory data changes in your directives. 基本上,您需要的是在指令中共享工厂数据更改。 So you can bind your desired factory data using different approaches based on your requirements(ie @ attribute,= 2 way model, & expression bindings) in directives and than watch those variables in directives link functions (ie ideal place where you needs to handle those watch conditions) for changes so once anything will update on factory (through button click), it will automatically propagated in your directives. 因此,您可以根据指令中的要求(即@ attribute,= 2方式模型和表达式绑定)使用不同的方法来绑定所需的工厂数据,而不是在指令中观察那些变量链接函数(即需要处理这些变量的理想位置)监视条件)以进行更改,因此一旦工厂中有任何更新(通过单击按钮),它将自动在您的指令中传播。 Here is the example to do different bindings. 是进行不同绑定的示例。

var myModule = angular.module('myModule', [])
.directive('myComponent', function () {
    return {
        restrict:'E',
        scope:{
            /* NOTE: Normally I would set my attributes and bindings
            to be the same name but I wanted to delineate between 
            parent and isolated scope. */                
            isolatedAttributeFoo:'@attributeFoo',
            isolatedBindingFoo:'=bindingFoo',
            isolatedExpressionFoo:'&'
        }        
    };
})


<my-component attribute-foo="{{foo}}" binding-foo="foo" 
isolated-expression-foo="updateFoo(newFoo)" >
    <h2>Attribute</h2>
    <div>
        <strong>set:</strong> <input ng-model="isolatedAttributeFoo">
        <i>// This does not update the parent scope.</i>
    </div>
    <h2>Binding</h2>
    <div>
        <strong>get:</strong> {{isolatedBindingFoo}}
    </div>
    <h2>Expression</h2>    
    <div>
        <input ng-model="isolatedFoo">
        <button class="btn" ng-click="isolatedExpressionFoo({newFoo:isolatedFoo})">
            Submit</button>
        <i>// And this calls a function on the parent scope.</i>
    </div>
</my-component>

I have made sample demo to illustrate the approach please check this . 我已经制作了示例演示来说明该方法,请对此进行检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM