父隔离范围仅在Firefox中更新一次

时间:2016-08-05 10:43:15

标签: angularjs firefox angularjs-directive scope watch

我正在尝试在子自定义指令中触发onchange事件时更新父范围变量。 我在child指令中使用的事件是input文件,由jqLit​​e触发onchange。那意味着, 在角度范围之外的操作。要更新范围,我正在使用scope.$evalAsync函数(已尝试$timeoutscope.$apply)。在父母自定义指令中,我使用$watch函数作为监听器。

请查看jsfiddle完整示例

标记

<div ng-app='myApp'>
  <parent></parent>
</div>

脚本

var myApp = angular.module('myApp', []);

myApp.directive('parent', function() {

  return {
    restrict: 'E',
    template: '<div class="parent">Parent' + '<span class="file-name">{{selectedFileName}}</span>' + '<child files="files"></child>' + '</div>',
    scope: {
      files: '='
    },
    link: function(scope){
        scope.$watch('files', function(newVal) {
        if (newVal && newVal.length > 0) {
          scope.selectedFileName = "selected file name: " + newVal[0].name;
        }
      });
    }
  };
});

myApp.directive('child', function() {

  return {
    restrict: 'E',
    template: '<div class="child">Child<br />' + '<span class="file-name">{{selectedFileName}}</span>' + '<file-upload files="files"></file-upload>' + '</div>',
    scope: {
      files: '='
    },
    link: function(scope) {
      scope.$watch('files', function(newVal) {
        if (newVal && newVal.length > 0) {
          scope.selectedFileName = "selected file name: " + newVal[0].name;
        }
      });
    }
  };
});

myApp.directive('fileUpload', function() {

  return {
    restrict: 'E',
    template: '<input type="file" />',
    scope: {
      files: '='
    },
    link: function(scope, element) {
      element.bind('change', function(e) {
        scope.$evalAsync(function() {
          scope.files = (e.srcElement || e.target).files;
        });
      });
    }
  };
});

在示例中,每次我选择新文件时,父范围变量files都会完美更新,并调用其$watch函数。

问题是在Firefox中,父级范围$watch函数只调用一次。仅在第一次。

提前致谢

1 个答案:

答案 0 :(得分:0)

<强>解决。

感谢这个post,它指出我的问题是我正在使用$watch

根据以下解释:

  

默认情况下,$watch不检查对象是否相等,只是为了   参考

就我而言,我正在观看一个阵列。它的引用没有改变,这就是为什么没有调用$watch函数的原因。实际改变的是,它只是数组的内部属性。因此,解决方案是使用$watchCollection()代替,其中:

  

浅看物体的属性并在任何时候发射   属性改变......对于数组,这意味着要观察数组项

为什么$watch在Firefox中不起作用,但在Chrome和IE中运行良好?答案是关于文件输入change事件的实现。 Firefox总是触发change事件,即使向其上传相同的文件也是如此。这 Chrome和IE中的行为。因此,Firefox显然在每个files事件上保留相同的change数组对象,并且仅更改其内部项。显然,Chrome和IE会在每个files事件中创建新的change对象,但在上传具有相同名称的文件时不会触发事件。