如何在AngularJS中连接相邻的隔离范围

时间:2016-01-21 16:42:05

标签: angularjs angularjs-directive angularjs-scope angularjs-controller

我还在学习AngularJS,我有一个概念性问题:在AngularJS中连接两个相邻的隔离范围的最佳方法是什么?通过“相邻”范围,我的意思是在层次上的同一级别。请考虑以下页面结构:

<div id="1" data-ng-app="angularApp">

    <div id="1A" data-ng-controller="colorCtrl as colorVm">
        <select data-ng-model="colorList" data-ng-options="color as color.name for color in colorVm.colors">
            <option>{{ color.name }}</option>
        </select>
    </div>

    <div id="1B" data-ng-controller="secondCtrl as secondVm">
        <light-color />
    </div>

    <div id="1C" data-ng-controller="thirdCtrl as thirdVm">
        <light-color />
    </div>

</div>

div#1B和div#1C中的'浅色'指令需要能够从div#1A的选择菜单中访问信息。如果不将“colorCtrl”分配给div#1并扩展其范围,最好的方法是什么?任何想法将不胜感激。

4 个答案:

答案 0 :(得分:2)

您可以在每个控制器中注入一个公共工厂,作为在3个部分之间共享数据的方法。

function colorCtrl($scope, ..., colorFactory){
  // use colorFactory for modifying/storing color data
}

function secondCtrl($scope, ..., colorFactory){
  // use colorFactory for modifying/storing color data
}

function thirdCtrl($scope, ..., colorFactory){
  // use colorFactory for modifying/storing color data
}

答案 1 :(得分:0)

您可以使用scope events

<div id="1A" data-ng-controller="colorCtrl as colorVm">
    <select ng-change="colorVm.colorChanged(selectedColor)" data-ng-model="selectedColor" data-ng-options="color as color.name for color in colorVm.colors">
        <option>{{ color.name }}</option>
    </select>
</div>

当用户从选择菜单中选择颜色colorVm.colorChanged()时,将使用模型值selectedColor调用该颜色。然后在colorCtrl

function ColorCtrl($scope, $rootScope) {
    this.colors = [...];
    this.colorChanged = function(selectedColor) {
       $rootScope.$broadcast('colorChanged', selectedColor);
    }
}

然后在secondCtrl你可以做到:

function SecondCtrl($scope) {
    $scope.$on('colorChanged', function(event, color) {
        console.log(color + ' has been selected');
    });
}

您还可以在指令link函数中监听范围事件:

...
link: function(scope) {
    scope.$on('colorChanged', function(event, color) {
        console.log(color + ' has been selected');
    });
}
...

答案 2 :(得分:0)

初始化父作用域上的对象。让您的ng-model指令连接到该对象的属性。该对象将由子范围继承。

AngularJS团队建议在控制器中完成初始化。在此示例中,我使用ng-init进行说明。在生产代码中,初始化最好在控制器中完成。

<div id="1" data-ng-app="angularApp">
    <div ng-init="x='{}'"></div>
    <div id="1A" data-ng-controller="colorCtrl as colorVm">
        <select ng-model="x.colorList" 
                ng-options="color as color.name for color in colorVm.colors">
        </select>
    </div>

    <div id="1B" data-ng-controller="secondCtrl as secondVm">
        <light-color color='x.colorList'/>
    </div>

    <div id="1C" data-ng-controller="thirdCtrl as thirdVm">
        <light-color color='x.colorList'/>
    </div>

</div>

在具有隔离范围的指令中,将属性设置为变量名称,并使用双向绑定声明该属性。

angular.module('angularApp').directive('lightColor', function() {
    return {
        restrict: 'E',
        scope: {color: '='},
        template: '<p> lightColor color.name={{color.name}}</p>'
    }
})

请记住,ng-model的规则始终使用点。

DEMO on JSFiddle

答案 3 :(得分:0)

我最终能够实现这一目标的方法是创建一个与所有三个控制器交互的服务。该文件现在看起来像这样:

if (pitch > 10)
{ 
    if(counter++ > X)
    {
        //display icon
    }
}
else
    counter = 0; // reset

还有一个服务(colorHelper.service.js),如下所示:

<div id="1" data-ng-app="angularApp">

    <div id="1A" data-ng-controller="colorCtrl as colorVm">
        <select data-ng-model="colorVm.colorHelper.colorPick" data-ng-options="color as color.name for color in colorVm.colors">
            <option>{{ color.name }}</option>
        </select>
    </div>

    <div id="1B" data-ng-controller="secondCtrl as secondVm">
        <light-color light-color-choice="{{ secondVm.colorHelper.colorPick.name }}" />
    </div>

    <div id="1C" data-ng-controller="thirdCtrl as thirdVm">
        <light-color light-color-choice="{{ thirdVm.colorHelper.colorPick.name }}" />
    </div>

</div>

&#39; colorHelper&#39;服务被输入每个控制器的参数。然后,每个控制器都有一个新属性,该属性设置为等于该控制器的colorHelper服务,即

angular
    .module('angularApp')
    .service('colorHelper', function() {

        var self = this;

        self.colorPick;

    return self;
});

这样,每个控制器都可以通过colorHelper.colorPick.name属性访问colorVm.colorHelper.colorPick ng-model。