Javascript 处理角度范围而不是$parent.$parent的正确方法

Javascript 处理角度范围而不是$parent.$parent的正确方法,javascript,angularjs,Javascript,Angularjs,我读了几篇文章,还没有找到解决我问题的例子 我的理解是: ng if和ng repeat创建隔离作用域 使用$parent.someProperty是错误的 使用$parent.$parent.someProperty将是一种令人憎恶的行为 那么,对于给定的模板标记,如何正确地绑定控制器以更新控制器属性 标记: (注意嵌套的ng if和ng repeat,创建一种$parent.$parent情况) {{item}} {{checkSetting()}} JavaScript var myA

我读了几篇文章,还没有找到解决我问题的例子

我的理解是:

  • ng if
    ng repeat
    创建隔离作用域
  • 使用
    $parent.someProperty
    是错误的
  • 使用
    $parent.$parent.someProperty
    将是一种令人憎恶的行为
  • 那么,对于给定的模板标记,如何正确地绑定控制器以更新控制器属性

    标记:
    (注意嵌套的
    ng if
    ng repeat
    ,创建一种
    $parent.$parent
    情况)

    
    {{item}}
    {{checkSetting()}}
    
    JavaScript

    var myApp = angular.module('MyApp', []);
    
    myApp.controller('MyCtrl', function($scope) {
      $scope.settings = {
        someProperty: '',
        anotherProperty: 'Hello'
      }
    
      $scope.repeatingItems = [
        'One',
        'Two',
        'Three'
      ];
    
      $scope.showOnCondition = true;
    
      $scope.checkSetting = function() {
        // When calling checkSettings(), I would like to access the value of someProperty here
        return $scope.settings;
      }
    });
    
    myApp.directive('setting', function() {
      return {
        restrict: 'E',
        require: '^myCtrl',
        // HOW DO I SOLVE THIS?
        // $parent.$parent is bad.
        template: '<input type="radio" ng-model="$parent.$parent.settings.someProperty" name="mySetting" value="{{item}}" />',
        scope: {
          settings: '=',
          item: '='
        }
      };
    });
    
    var myApp=angular.module('myApp',[]);
    myApp.controller('MyCtrl',函数($scope){
    $scope.settings={
    someProperty:“”,
    另一个属性:“你好”
    }
    $scope.repeatingItems=[
    "一",,
    “两个”,
    “三个”
    ];
    $scope.showOnCondition=true;
    $scope.checkSetting=函数(){
    //调用checkSettings()时,我想在此处访问someProperty的值
    返回$scope.settings;
    }
    });
    myApp.directive('setting',function(){
    返回{
    限制:'E',
    要求:“^myCtrl”,
    //我如何解决这个问题?
    //$parent.$parent不好。
    模板:“”,
    范围:{
    设置:“=”,
    项目:'='
    }
    };
    });
    
    给出上述示例,如何正确构造指令和/或标记以访问控制器中的
    设置.someProperty
    ?还是我需要做一些完全不同的事情

    澄清
    我试图做的事情似乎有些混乱。指令中提供了
    someProperty
    ,可以正常工作。请注意,我正在尝试从指令中为控制器的
    someProperty
    属性赋值(使用ng模型)

    更新
    我已经将上面的代码修改为已知的工作代码,并添加了一个。 请注意,它可以工作,但在模板中使用了
    $parent.$parent
    。这是我需要了解如何解决的问题。

    编辑

    我完全重写了我的答案,基于您的小提琴和更简单的双向数据绑定方法。未来读者请注意,前几条评论与此更新答案不再相关

    HTML

    
    {{item}}
    {{checkSetting()}}
    
    JS

    var myApp=angular.module('myApp',[]);
    myApp.controller('MyCtrl',函数($scope){
    $scope.settings={
    someProperty:true,
    另一个属性:“你好”
    }
    $scope.repeatingItems=[
    "一",,
    “两个”,
    “三个”
    ];
    $scope.showOnCondition=true;
    $scope.checkSetting=函数(){
    //调用checkSettings()时,我想在此处访问someProperty的值
    返回$scope.settings;
    }
    });
    myApp.directive('setting',function(){
    返回{
    限制:'E',
    替换:正确,
    模板:“”,
    范围:{
    测试:'=',
    项目:'='
    }
    };
    });
    

    这在父控制器属性和指令之间提供了双向数据绑定。使用这种方法,您可以将每个单独的父作用域属性传递给一个属性,并将其绑定到隔离作用域中。

    当层次关系和数据传递变得复杂时,一个选项是将父/子关系解耦,只使用一个服务共享数据


    我已经看到了一些很好的解释,例如,关于。您还可以将此想法应用于通用缓存服务,如Angular,或者更复杂的库:。

    为什么不添加一个参数“someproperty”以传递到设置指令=类似这样:

    myApp.directive('setting', function() {
       return {
       restrict: 'E',
       template: '<input type="radio" ng-model="myProperty" 
       value="{{item}}" />',
       scope: {
          settings: '=',
          item: '=',
          myProperty: '='
       }
      };
    });
    
    myApp.directive('setting',function(){
    返回{
    限制:'E',
    模板:“”,
    范围:{
    设置:“=”,
    项目:'=',
    myProperty:“=”
    }
    };
    });
    
    在您的标记中:

    <label ng-repeat="item in repeatingItems">
      {{item}}
      <setting item="item" myProperty="settings.someProperty" />
    </label>
    
    
    {{item}}
    
    您可以将设置传递给指令,我认为这是最简单/最直接/最干净的方法

    Angular将
    设置
    作为
    MyCtrl.settings
    正确计算,然后将其传递到
    设置
    指令的隔离范围。在指令内部,
    设置
    上有双向绑定,因此可以从那里更新设置

    修改示例时,将
    设置
    传递到标记中的指令中

    然后在JavaScript中,将其替换为模板:

    模板:“”,


    下面是一个。

    看看这就是您要做的吗?不,这是一个不包含嵌套隔离作用域的简单示例。首先,作用域不是隔离的,所以您可以在这里使用作用域继承。那么controllerAs方法在这种情况下始终有效。@dfsq-子作用域/指令没有与控制器“对话”。至于“controllerAs”方法,谢谢,但我不知道那是什么意思!我很感谢你的帮助,但是你说的是相当笼统的话,我正在寻找一些具体的方法来帮助我了解这一点。我听说过这个概念,但仅仅将模板上的输入值输入到父控制器中似乎会有很大的开销。我一直在想一定有更简单的方法?你是对的-我终于绞尽脑汁,给出了一个更简单的答案,但可能会将其保留为解耦服务的数据点。好的地方,@cale_b,添加了相关的代码位,谢谢你的提示。myProperty参数是双向数据绑定,对吗?因此,新的parm“myProperty=setting.someProperty”绑定到控制器$scope.settings。如果child指令更改了i
    var myApp = angular.module('MyApp', []);
    
    myApp.controller('MyCtrl', function($scope) {
      $scope.settings = {
        someProperty: true,
        anotherProperty: 'Hello'
      }
    
      $scope.repeatingItems = [
        'One',
        'Two',
        'Three'
      ];
    
      $scope.showOnCondition = true;
    
      $scope.checkSetting = function() {
        // When calling checkSettings(), I would like to access the value of someProperty here
        return $scope.settings;
      }
    });
    
    myApp.directive('setting', function() {
      return {
        restrict: 'E',
            replace: true,
        template: '<input type="radio" ng-model="test" name="mySetting" value="{{item}}" />',
        scope: {
          test: '=',
          item: '='
        }
      };
    });
    
    myApp.directive('setting', function() {
       return {
       restrict: 'E',
       template: '<input type="radio" ng-model="myProperty" 
       value="{{item}}" />',
       scope: {
          settings: '=',
          item: '=',
          myProperty: '='
       }
      };
    });
    
    <label ng-repeat="item in repeatingItems">
      {{item}}
      <setting item="item" myProperty="settings.someProperty" />
    </label>