父范围未使用 ng-change from 指令从 select 更新

Parent scope not updating from select with ng-change from directive

我看过几篇这方面的文章,但还是搞不懂。

我无法从指令中更新父作用域。我读过文章说范围值不应该是原始的,而应该是一个对象,但仍然无法弄清楚为什么这不起作用。

angular.module('moduleMihai').controller('someController',
    ['$scope', '$http', function ($scope, $http) {

            $scope.durations = [{
                field: 'yearly',
                title: 'Yearly'
            }, {
                field: 'monthly',
                title: 'Monthly'
            }, {
                field: 'weekly',
                title: 'Weekly'
            }];
            $scope.selectedDuration = $scope.durations[0];

            $scope.handleDurationSelection = function () {
                console.log($scope.selectedDuration.field + ' selected');
                $scope.someData.title[0] = "SOMETHING ELSE!!";
            };


            $scope.someData= {
                title: ['Value1', 'Value2', 'Value3'] };
}]);

指令中没有任何内容:

angular.module("awaCommon").directive("durationSelection", [
    function () {
        return { 
            scope: {}, // tried removing this as well as seen in some articles 
            restrict: "E",
            templateUrl: "duration-selection.html",
            link: function ($scope, $element, $attr) {
            }
        }
    }
]);

低于包含 select:

的持续时间-selection.html
<div ng-controller="someController">
<div>
    Child: {{someData.title[0]}}
    <select
        ng-options="item.title for item in durations"
        ng-model="selectedDuration"
        ng-change="handleDurationSelection()">
    </select>
</div>

因此子项中的上述值:{{someData.title[0]}} - 当值被 selected 时正确更新。但是这里的那个 - 父级:{{someData.title[0]}},在主要路线中不是:

<div ng-controller="someController">
<div>
    Parent: {{someData.title[0]}}
    <duration-selection></duration-selection>
</div>

我需要更新父作用域以更新不同的指令

从指令交互和更新父范围的方法是使用

  • 事件处理(发出和广播)Todd about events $emit and $broadcast:所以这里我们在子指令发生变化时提醒父级,然后父级监听事件。 由于一些不好的方面,我建议尽量少用
  • 指令属性传递函数:我们将要处理的函数传递给我们的指令,以便在需要时从指令中处理或调用它(对我来说最好的方法)
  • 在指令中更新$scope.$parent.lngBusinessUnit,不需要再次将函数传递给指令,没有必要。因为指令是处理逻辑的指令。我们直接直接更新父级。
  • 在父指令上使用 $watch 来帮助检查 selectedDuration $watch read more 的变化:这很容易,因为我们将 ngModel 映射到传递的我们指令的参数在我们的 return->scope "=" 中使用双向绑定来自指令设置

上述每种可能性的示例

  • 事件处理

angular.module("eventTest", [])
.controller("mainCtrl", function ($scope){
  console.log("am here");
$scope.parentValue = "test";
$scope.valueToPass = ["Male", "Female"];


//let's catch the updated content
$scope.$on('childUpdated', function(event, value){
  $scope.parentValue = value;
  console.log("updated from child directive", value);
});


})
.directive("child", function(){
return {
  restrict:'E',
  scope: {
  valueToPass:"="
  },
  templateUrl:"child.html",
  controller: function ($scope){
  //this is method is triggered when the select of our valueToPass is changed
  $scope.childChanges = function (value){
      $scope.$emit('childUpdated', value);
      console.log("child emitted this:", value);
   }
  }
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="eventTest"> 
<div ng-controller="mainCtrl">
<h1>Event Test Just for your case, advise you read up</h1>
Parent: <b>{{parentValue}}</b>
<br>
<child value-to-pass="valueToPass"></child>
</div>


<script type='text/ng-template' id="child.html">
Child value : <b>{{menu}}<b> <br>
<select ng-model="menu" ng-change="childChanges(menu)">
  <option ng-repeat="item in valueToPass">{{item}}</option>
</select>
</script>

</body>

  • 指令属性,使用函数

angular.module("eventTest", [])
    .controller("mainCtrl", function ($scope){
      console.log("am here");
    $scope.parentValue = "test";
    $scope.primaryVariable = "Male";
    
    $scope.onChange = function (){
     $scope.parentValue = $scope.primaryVariable;
    }
   

    })
    .directive("child", function(){
    return {
      restrict:'E',
      scope: {
      primaryVariable:"=",
      callMe:"&"//note this syntax, check angular directive doc
      },
      templateUrl:"child.html",
      controller: function ($scope){
       $scope.valueToPass = ["Male", "Female"];
      //this is method is triggered when the select of our primaryVarible is changed
      $scope.childChanges = function (){
        $scope.callMe();
       }
      }
    }
    });
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

    <body ng-app="eventTest"> 
    <div ng-controller="mainCtrl">
    <h1>Directive Function Passing</h1>
    Parent: <b>{{parentValue}}</b>
    <br>
    <child primary-variable="primaryVariable" call-me="onChange()"></child>
    </div>


    <script type='text/ng-template' id="child.html">
    Child value : <b>{{primaryVariable}}<b> <br>
    <select ng-model="primaryVariable" ng-change="childChanges()">
      <option ng-repeat="item in valueToPass">{{item}}</option>
    </select>
    </script>

    </body>

  • 正在使用作用域。$parent

 angular.module("eventTest", [])
        .controller("mainCtrl", function ($scope){
          console.log("am here");
        $scope.parentValue = "test";
        $scope.primaryVariable = "Male";
         

        })
        .directive("child", function(){
        return {
          restrict:'E',
          scope: {
          primaryVariable:"="
          },
          templateUrl:"child.html",
          controller: function ($scope){
           $scope.valueToPass = ["Male", "Female"];
          //this is method is triggered when the select of our primaryVarible is changed
          $scope.childChanges = function (){
            $scope.$parent.parentValue = $scope.primaryVariable;
           }
          }
        }
        });
     <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

        <body ng-app="eventTest"> 
        <div ng-controller="mainCtrl">
        <h1>Using $parent</h1>
        Parent: <b>{{parentValue}}</b>
        <br>
        <child primary-variable="primaryVariable"></child>
        </div>


        <script type='text/ng-template' id="child.html">
        Child value : <b>{{primaryVariable}}<b> <br>
        <select ng-model="primaryVariable" ng-change="childChanges()">
          <option ng-repeat="item in valueToPass">{{item}}</option>
        </select>
        </script>

        </body>

  • 使用 $watch

angular.module("eventTest", [])
        .controller("mainCtrl", function ($scope){
          console.log("am here");
        $scope.parentValue = "test";
        $scope.primaryVariable = "Male";
         
         $scope.$watch('primaryVariable', function(){
         $scope.parentValue = $scope.primaryVariable;
         
         });
         
        })
        .directive("child", function(){
        return {
          restrict:'E',
          scope: {
          primaryVariable:"="
          },
          templateUrl:"child.html",
          controller: function ($scope){
           $scope.valueToPass = ["Male", "Female"];
          }
        }
        });
     <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

        <body ng-app="eventTest"> 
        <div ng-controller="mainCtrl">
        <h1>using $watch</h1>
        Parent: <b>{{parentValue}}</b>
        <br>
        <child primary-variable="primaryVariable"></child>
        </div>


        <script type='text/ng-template' id="child.html">
        Child value : <b>{{primaryVariable}}<b> <br>
        <select ng-model="primaryVariable" ng-change="childChanges()">
          <option ng-repeat="item in valueToPass">{{item}}</option>
        </select>
        </script>

        </body>

希望对您有所帮助