指令范围设置为true时的奇怪行为

时间:2016-07-15 09:02:23

标签: javascript angularjs angularjs-scope

是Angular的新手,当其范围设置为true时遇到了Custom Directive的这种奇怪行为。在这种情况下,AngularJS将通过继承父作用域(通常是控制器作用域,否则是应用程序的rootScope)来创建新作用域。因此,在Parent中进行的任何更改都将反映给child,反之亦然。此行为在此JSFiddle link

中不一致

HTML:

<div ng-app="schoolApp">

  <div ng-controller="schoolCtrl">
    <h2 ng-click="reverseName()">{{schoolName}}, Click me to reverse school name</h2>

    <h2>Student Name : {{student.firstName}} {{student.lastName}}<br>
            Student Contact Num : {{student.mobileNum}}
        </h2>
    <div>Edit in parent :
      <input type='text' ng-model='student.firstName'>
      <input type='text' ng-model='student.lastName'>
    </div>
    <div my-directive class='directive'></div>
  </div>
</div>

JS(Controller n Directive):

var app = angular.module("schoolApp", []);

app.controller("schoolCtrl", function($scope) {
  $scope.schoolName = 'Oxford Academy';
  $scope.reverseName = function() {
    $scope.schoolName = $scope.schoolName.split('').reverse().join('');
  };
  $scope.student = {
    firstName: 'Chris',
    lastName: 'Johnson',
    mobileNum: 123456
  }
});

app.directive("myDirective", function() {
  return {
    restrict: "EA",
    scope: true,
    template: "<strong>Inside Directive Scope</strong>" +
      "<div>School Name is : {{schoolName}}</div>" +
      "Change School name : <input type='text' ng-model='schoolName' />" +
      "<br><br>" +
      "<div> Student Details :</div>" +
      "Student Name : {{student.firstName}} {{student.lastName}}<br>" +
      "Student Contact Num : {{student.mobileNum}}" +
      "<br><br>" +
      "Change Student First Name : <input type='text' ng-model='student.firstName'/><br>" +
      "Change Student Last Name : <input type='text' ng-model='student.lastName'/><br>" +
      "Change Student Contact Number : <input type='text' ng-model='student.mobileNum'/>"
  };
});

问题场景:只要更改控制器(父作用域)中的学校名称,它反映在自定义指令(my-directive)中,但是一旦我更改了Child Scope中的学校名称,就会出现一些断开连接。儿童范围的变化都没有反映在父母身上,现在也没有反过来。

但是,在控制器(父范围)中更改学生名字或姓氏的相同步骤将显示在自定义指令(my-directive)中,而在子范围中更改学生名字或姓氏将反映在父范围内。无论你为Student First name n姓名进行了多少次更改迭代,它都能正常工作。

有人可以告诉我,我在做什么,或者有什么我需要明白的事情是在幕后工作吗?

3 个答案:

答案 0 :(得分:3)

  1. var jqxhr = $.getJSON(serverUrl, function(data) { console.log(data); //See it in Firebug, it's already a JSON. alert( JSON.stringify(data) ); //If you want to see it as string } (指令获得新范围) Angular没有在这里做任何事情,但奇怪的行为是因为JavaScript Prototypical继承。当一个孩子在父母身上改变scope : true时会发生什么,它最终会在孩子中创建一个值的副本,并打破继承链。这就是当primitive values (string, number, boolean)在指令(子范围)中被更改的原因它获得了自己的副本和继承链与父进行了抛弃
  2. 但是当你改变一个JS对象(在你的情况下是附加到$ scope的学生对象)时,情况并非如此,无论如何,继承链都将保持不变。

    1. schoolName(指令使用其父范围)
    2. 另一方面,如果您将范围设置为false,那么您的孩子将始终使用Parent范围,并且永远不会有机会破坏继承链。

      希望这会有所帮助: - )

答案 1 :(得分:1)

这是因为原型继承。您的指令继承父作用域的属性,这意味着,指令范围schoolName将具有与父作用域schoolName相同的值,以及student属性将指向与父作用域student属性相同的对象。

更改schoolName的值时,只需更改范围上的字符串属性即可。更改student.firstName时,更改从父目录和指令范围引用的对象的字符串属性。

答案 2 :(得分:-1)

您的方法$scope.$digest();中缺少reverseSchoolName,例如:

$scope.reverseSchoolName = function() {
    $scope.schoolName = $scope.schoolName.split('').reverse().join('');
    $scope.$digest();
};

一条建议:不要使用scope: true。尝试传递每个参数,例如scope: {schoolName: '=', student: '='}要获得一个独立的范围,请参阅https://docs.angularjs.org/guide/directive#isolating-the-scope-of-a-directive