在子指令之间共享数据 [英] Sharing Data between Child Directives

查看:21
本文介绍了在子指令之间共享数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定义了三个指令:

  • 家长

    这应该在其他两个指令之间共享变量 - 儿童一和儿童二.

  • 儿童一号

    这包含一个表示搜索词的输入字段.每当这种变化时,我都会使用链接函数来更新存储在父控制器中的变量.

    在实际使用中,我将根据这个词进行搜索并更新数组.但在这个例子中,为了简单起见,我只想创建一个长度为 1 的新数组,我想用它的值填充搜索词.

  • 二孩

    这应该显示结果数组.

出于某种原因,这不起作用,如果我将数组的长度设置为 0 并推送值,我将看到子二中的视图更新(我已注释掉实现此目的的代码),但我想了解为什么设置数组值不起作用.

我知道一个服务适合这里,但是这个指令可能会在同一页面上多次重复使用,所以我不希望页面上的每个项目之间的范围发生冲突.

为什么视图没有使用我当前使用的代码进行更新?

var app = angular.module('示例应用程序', []).directive('parent', function() {返回 {限制:'E',转置:真实,模板:<div ng-transclude></div>",控制器:功能($范围){this.searchTerm = "";this.arrayContainingSearchTerm = [{value: ''}];this.updateSearchTerm = 函数(searchTerm){this.searchTerm = searchTerm;//当这个数组被分配时 - 它不会在视图中更新this.arrayContainingSearchTerm = [{value: searchTerm}];//这将更新视图.//this.arrayContainingSearchTerm.length = 0;//this.arrayContainingSearchTerm.push([{value: searchTerm}]);};}}}).directive('childOne', function() {返回 {限制:'E',要求:'^^父母',模板:<div><h1>孩子一</h1><input ng-model='searchTerm'></input></div>",链接:函数(范围、元素、属性、父控制器){scope.$watch('searchTerm', function(newValue, oldValue) {parentController.updateSearchTerm(newValue);});}}}).directive('childTwo', function() {返回 {限制:'E',要求:'^^父母',模板:<div><h1>子二</h1><h2>下面的值应该是:{{searchTerm}}</h2><h2>{{arrayContainingSearchTerm}}</h2>

",链接:函数(范围、元素、属性、父控制器){scope.searchTerm = parentController.searchTerm;scope.arrayContainingSearchTerm = parentController.arrayContainingSearchTerm;}}})

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script><div ng-app="示例应用程序"><父母><一个孩子></一个孩子><child-two></child-two></父母>

解决方案

子级作用域自动继承父级作用域,可以通过 $parent/要求父级控制器专门访问父级作用域,但注意兄弟级不能[轻松]访问每个其他范围.因此,解决方案是更新父作用域并将父作用域更改反映回目标子级.

您不需要更新子作用域,因为子作用域是自动从父作用域继承的.另外,不要观看 searchTerm ngModel,只需在 childOne 指令中使用 attrs.ngModel.

var app = angular.module('示例应用程序', []).directive('parent', function() {返回 {限制:'E',转置:真实,模板:<div ng-transclude></div>",控制器:功能($范围){this.searchTerm = "";this.arrayContainingSearchTerm = [{value: ''}];this.updateSearchTerm = 函数(searchTerm){this.searchTerm = searchTerm;//当这个数组被分配时 - 它不会在视图中更新this.arrayContainingSearchTerm = [{value: searchTerm}];//这将更新视图.//this.arrayContainingSearchTerm.length = 0;//this.arrayContainingSearchTerm.push([{value: searchTerm}]);};}}}).directive('childOne', function() {返回 {限制:'E',要求:'^^父母',模板:<div><h1>孩子一</h1><input ng-model='searchTerm'></input></div>",链接:函数(范围、元素、属性、父控制器){//只需使用 attrs.ngModelparentController.updateSearchTerm(attrs.ngModel);}}}).directive('childTwo', function() {返回 {限制:'E',要求:'^^父母',模板:<div><h1>子二</h1><h2>下面的值应该是:{{searchTerm}}</h2><h2>{{arrayContainingSearchTerm}}</h2>

",链接:函数(范围、元素、属性、父控制器){//注释/删除它,因为作用域是从父作用域自动继承的//scope.arrayContainingSearchTerm = parentController.arrayContainingSearchTerm;//scope.searchTerm = parentController.searchTerm;//scope.arrayContainingSearchTerm = parentController.arrayContainingSearchTerm;}}})

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script><div ng-app="示例应用程序"><父母><一个孩子></一个孩子><child-two></child-two></父母>

I have three directives defined:

For some reason this does not work, if I set the length of the Array to 0 and push the value I will see the view update in Child Two (I have commented out the code which achieves this), but I want to understand why setting the array value doesn't work.

I understand that a service would be suitable here, but this directive may be re-used multiple times on the same page so I don't want the scope to clash between each item on the page.

Why doesn't the view get updated with the code I currently use?

var app = angular
  .module('SampleApplication', [])
  .directive('parent', function() {
    return {
      restrict: 'E',
      transclude: true,
      template: "<div ng-transclude></div>",
      controller: function($scope) {
        this.searchTerm = "";
        this.arrayContainingSearchTerm = [{value: ''}];
      
        this.updateSearchTerm = function(searchTerm) {
          this.searchTerm = searchTerm;
          
          //When this array is assigned - it doesn't get updated in the view
          this.arrayContainingSearchTerm = [{value: searchTerm}];
          
          //This will update the view.
          //this.arrayContainingSearchTerm.length = 0;
          //this.arrayContainingSearchTerm.push([{value: searchTerm}]);
        };
        
      }
    }
  })
  .directive('childOne', function() {
    return {
      restrict: 'E',
      require: '^^parent',
      template: "<div><h1>Child One</h1><input ng-model='searchTerm'></input></div>",
      link: function(scope, element, attrs, parentController) {
        scope.$watch('searchTerm', function(newValue, oldValue) {
          parentController.updateSearchTerm(newValue);
        });
      }
    }
  })
  .directive('childTwo', function() {
    return {
      restrict: 'E',
      require: '^^parent',
      template: "<div><h1>Child Two</h1><h2>Value below should be: {{searchTerm}}</h2><h2>{{arrayContainingSearchTerm}}</h2></div>",
      link: function(scope, element, attrs, parentController) {
        scope.searchTerm = parentController.searchTerm;
        scope.arrayContainingSearchTerm = parentController.arrayContainingSearchTerm;
      }
    }
  })

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>


<div ng-app="SampleApplication">
  <parent>
    <child-one></child-one>
    <child-two></child-two>
  </parent>
</div>

解决方案

Children scope automatically inherit the parent's scope and can specifically access the parent's scope with $parent / requiring the parent controller but take note that siblings cannot [easily] access each others scope. So, the solution is to update the parent scope and reflect the parent scope changes back to the targeted child.

You don't need to update the child scope since the child scope is automatically inherit from parent scope. Also rather than watch the searchTerm ngModel, just use attrs.ngModel in the childOne directive.

var app = angular
.module('SampleApplication', [])
.directive('parent', function() {
  return {
    restrict: 'E',
    transclude: true,
    template: "<div ng-transclude></div>",
    controller: function($scope) {
      this.searchTerm = "";
      this.arrayContainingSearchTerm = [{value: ''}];

      this.updateSearchTerm = function(searchTerm) {
        this.searchTerm = searchTerm;

        //When this array is assigned - it doesn't get updated in the view
        this.arrayContainingSearchTerm = [{value: searchTerm}];

        //This will update the view.
        //this.arrayContainingSearchTerm.length = 0;
        //this.arrayContainingSearchTerm.push([{value: searchTerm}]);
      };

    }
  }
})
.directive('childOne', function() {
  return {
    restrict: 'E',
    require: '^^parent',
    template: "<div><h1>Child One</h1><input ng-model='searchTerm'></input></div>",
    link: function(scope, element, attrs, parentController) {
        // Just use attrs.ngModel
        parentController.updateSearchTerm(attrs.ngModel);
    }
  }
})
.directive('childTwo', function() {
  return {
    restrict: 'E',
    require: '^^parent',
    template: "<div><h1>Child Two</h1><h2>Value below should be: {{searchTerm}}</h2><h2>{{arrayContainingSearchTerm}}</h2></div>",
    link: function(scope, element, attrs, parentController) {
       // Comment/remove this since the scope is automatically inherit from parent scope
      //scope.arrayContainingSearchTerm = parentController.arrayContainingSearchTerm;
      //scope.searchTerm = parentController.searchTerm;
       // scope.arrayContainingSearchTerm = parentController.arrayContainingSearchTerm;

    }
  }
})

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>


<div ng-app="SampleApplication">
  <parent>
    <child-one></child-one>
    <child-two></child-two>
  </parent>
</div>

这篇关于在子指令之间共享数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆