AngularJS + IE 11 + Polymer = ng-model不更新

时间:2016-05-09 10:59:05

标签: javascript angularjs internet-explorer polymer internet-explorer-11

在我的应用程序的指令中,我有一个带有使用ng-model绑定的变量的文本输入:

<input type="text" class="text-input" ng-change="onInputChange()" ng-model="value" />

我在链接功能中设置了以下内容:

scope.onInputChange = function() {
   console.log(scope.value);
};

scope.$watch('value', function(value) {
   console.log(value);
});

setInterval(function(){
   console.log(scope.value);
}, 500);

当我输入输入字段时,从不触发ng-change和watch,并且间隔始终输出undefined。

在IE 11中的独立应用程序中运行此指令。

在Chrome中的独立应用程序中运行此指令(最新版)有效。

在Chrome中运行我的整个应用程序(最新版)。

我的应用程序中可能导致此行为的原因是什么?

编辑2:

这种情况似乎是由webcomponents.js引起的。当此文件包含在IE 11中时,它会从DOM元素中删除所有事件侦听器,并用它自己的dispatchOriginalEvent函数替换它们。在指定的输入字段上,它无法替换任何正常的事件侦听器,因此不会注意到任何文本输入。

编辑3:

我已经将问题进一步缩小到Angular的ng-include和webcomponents.js polyfill for ShadowDOM的组合。因此,我向webcomponentsjs的github实例添加了一个问题

编辑:完整指令

'use strict';

(function(angular) {

    angular.module('givemeareason', [
        'config'
    ]);

    angular.module('givemeareason')
        .directive('giveMeAReason', ['$timeout', 'AppConfig', function($timeout, Appconfig) {
            return {
                restrict: 'EA',
                replace : true,
                template: '<div class="give-me-a-reason">' +
                    '<input type="text" class="reason" ng-change="onInputChange()" ng-model="reason" />' +
                    '</div>',
                require : 'ngModel',
                scope   : {
                    onChange: '&'
                },
                link    : function(scope, elm, attrs, ngModelContoller) {
                    scope.onInputChange = function() {
                        scope.onChange({
                            item: {reason: scope.reason},
                            valid: typeof scope.reason === 'string' && scope.reason.length > 0
                        });
                    };

                    scope.$watch('reason', function(reason) {
                        console.log(reason);
                    });

                    setInterval(function(){
                        console.log(scope.reason);
                    }, 500);
                }
            };
        }]);
    }(window.angular));

用法:

<give-me-a-reason id="paste-reason" ng-model="importVm.reasonModel" on-change="importVm.reasonChanged(item, valid)"></give-me-a-reason>

修改

控制台中出现以下错误。它们可能相关也可能不相关:

Object doesn't support property or method 'animate'. File: web-animations.min.js, Line 16, Column: 11207
Assertion failed. File: webcomponents.js, Line: 116, Column: 15

在探讨过度问题后,它们似乎与browsersync相关,如果没有它们,问题中描述的问题仍然存在。

2 个答案:

答案 0 :(得分:0)

传递函数中的值

<input type="text" class="text-input" ng-change="onInputChange(value)" ng-model="value" />

答案 1 :(得分:0)

ng-change删除input并修改您的指令代码,如下所示:

scope.onInputChange = function() {
    scope.onChange({
        item: {reason: scope.reason},
        valid: typeof scope.reason === 'string' && scope.reason.length > 0
    });
};

scope.$watch('reason', scope.onInputChange);

这对我来说很好。请参阅下面的工作示例:

angular.module('givemeareason', []);

angular.module('givemeareason')
  .controller("foocontroller", function($scope) {
    var vm = this;
    vm.reasonChanged = function(item, valid) {
      console.log("In the controller", item, valid);
    }
  });

angular.module('givemeareason')
  .directive('giveMeAReason', ['$timeout',
    function($timeout) {
      return {
        restrict: 'EA',
        replace: true,
        template: '<div class="give-me-a-reason">' +
          '<input type="text" class="reason" ng-model="reason" />' +
          '</div>',
        require: 'ngModel',
        scope: {
          onChange: '&'
        },
        link: function(scope, elm, attrs, ngModelContoller) {
          scope.onInputChange = function() {
            console.log("Changed value", scope.reason);

            scope.onChange({
              item: {
                reason: scope.reason
              },
              valid: typeof scope.reason === 'string' && scope.reason.length > 0
            });
          };

          scope.$watch('reason', scope.onInputChange);
        }
      };
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="givemeareason" ng-controller="foocontroller as importVm">
  <give-me-a-reason id="paste-reason" ng-model="importVm.reasonModel" on-change="importVm.reasonChanged(item, valid)"></give-me-a-reason>
</div>