在Angular中,如何检测输入是否被第三方代码更改?

时间:2015-12-30 16:18:56

标签: angularjs angularjs-directive

我在Angular中做了一些例子,我做了一些事情,以回应用户将数据键入输入元素。

我在链接功能中使用以下代码来检测并响应更改:

            $element.bind("keyup", listener);
            $element.bind("change", listener);
            $element.bind('paste cut', function () {
                $browser.defer(listener);
            }); 

这很好用,有一个很大的例外。我在同一输入上使用Kendo UI datepicker指令,允许用户在日历上选择日期。当用户通过单击日历更改日期时,我的代码不会捕获更改事件。

我使用Kendo UI的事实是任意的;我想我应该期待任何第三方Javascript代码的问题。

如何连接我的链接功能,以便在被其他Javascript代码修改时看到字段发生变化?

编辑:根据要求,这是一个问题的简化示例。它是一个包含文本字段和按钮的页面。当字段内容发生变化时,文本字段与Angular连接以弹出警告框。该按钮手动更改字段的值,Angular不会做任何事情。我希望它能够检测到这种变化并以弹出窗口响应。

<!DOCTYPE html>
<html ng-app="myApp">
<head>    
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body ng-controller="myController">
    When you type something in the box focus away from the input, Angular code pops an alert box.
    <br />
    <input
        id="foo"        
        alert />
    <input
        type="button"
        value="But click this button to change the contents of the box and no alert happens." 
        onclick="document.getElementById('foo').value = 'bar';"/>
    <script>
        angular.module("myApp", [])
        .controller("myController", ["$scope", function ($scope) {
            $scope.foo = "foo";
        }])
        .directive('alert', ['$browser',function ($browser) {
            return {                
                link: function ($scope, $element, $attrs, ngModel) {                    
                    function listener() {
                        alert("listener function invoked!");
                    }                    
                    $element.bind("change", listener);
                    $element.bind('paste cut', function () {
                        $browser.defer(listener);
                    });
                }
            };
        }]);
    </script>
</body>
</html>

2 个答案:

答案 0 :(得分:0)

我能够使用上面的评论作为指导找到答案。我稍后会对此进行编辑以使其更加完整,但简短的回答是需要ngModel并附加$ watch。

答案 1 :(得分:0)

以这种方式改变DOM是违背角度哲学的,我们为此留下了指令,这就是为什么角度没有抓住按钮的变化,我的意思就是在这一点:

<input
        type="button"
        value="But click this button to change the contents of the box and no alert happens." 
        onclick="document.getElementById('foo').value = 'bar';"/>

你最好这样做(这里只是HTML&amp; angular):

/*without directive*/
<input type="text" id="foo" ng-model="foo" />
<input type="button" value="Change value" onclick="changeVal()"/>

进入控制器(我添加了$ watch)

.controller("myController", ["$scope", function ($scope) {
            $scope.foo = "foo";

            //when button pressed
            $scope.changeVal() = function{
              $scope.foo = "new value";
            };

       //when the foo value change, the $watch catch it
       $scope.$watch('foo', function (newVal, oldVal) {
            var newValue = newVal;
            if (newVal != oldVal) {
               alert("value changed");
              //add here whatever code ..
            }
        });

    }])