父范围未从指令中使用 ng-change 进行选择更新

0 select scope parent angularjs ng-options

我看过几篇关于此的文章,但仍然无法弄清楚。

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

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'] };
}]);
Run Code Online (Sandbox Code Playgroud)

该指令中没有任何内容:

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) {
            }
        }
    }
]);
Run Code Online (Sandbox Code Playgroud)

在包含选择的duration-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>
Run Code Online (Sandbox Code Playgroud)

因此,子项中的上述值:{{someData.title[0]}} - 当选择值时会正确更新。但主路线中的父级:{{someData.title[0]}}不是:

<div ng-controller="someController">
<div>
    Parent: {{someData.title[0]}}
    <duration-selection></duration-selection>
</div>
Run Code Online (Sandbox Code Playgroud)

我需要更新父范围才能更新不同的指令

The*_*bee 5

从指令中交互和更新父作用域的方法是使用

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

示例 对于上述每种可能性

  • 事件处理

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);
   }
  }
}
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • 指令属性,使用函数

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();
       }
      }
    }
    });
Run Code Online (Sandbox Code Playgroud)
 <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>
Run Code Online (Sandbox Code Playgroud)

  • 使用作用域.$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;
           }
          }
        }
        });
Run Code Online (Sandbox Code Playgroud)
     <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>
Run Code Online (Sandbox Code Playgroud)

  • 使用 $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"];
          }
        }
        });
Run Code Online (Sandbox Code Playgroud)
     <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>
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助