Angularjs:我如何更新外部代码所做的DOM更改我无法控制?

时间:2014-10-12 02:57:54

标签: javascript angularjs google-chrome-extension html-form html-input

我正在使用Angular构建一个登录表单,并且还使用名为Password Hasher Plus的Chrome扩展程序。扩展的工作原理是将密码输入字段中的数据替换为密码的散列版本。

问题是当Chrome扩展程序将新数据注入密码字段时,模型不会更新。

当我搜索类似的问题时,我看到了使用$ scope。$ apply()作为解决方案的建议。据我所知,$ scope。$ apply()必须传递改变事物的代码。我的理解是否正确?在这种情况下,我无法访问代码,因为它在扩展名中。

这里更普遍的问题是,当你无法控制的外部JavaScript操纵DOM时,如何更新范围?

我的问题在以下示例代码中得到了证明。

示例视图

 <body ng-controller="MainCtrl">
    <input ng-model="password" type="password" name="password"/><br><br>
    <button type="submit" value="Submit" ng-click="submit()">
     Submit
    </button><br><br>
    <span>DOM Value: {{domValue}}</span><br>
    <span>Scope Value: {{scopeValue}}</span>
  </body>

示例控制器

app.controller('MainCtrl', function($scope) {

  $scope.submit = function(){
    $scope.domValue = document.getElementsByName("password")[0].value;
    $scope.scopeValue = $scope.password;
  };

});

此示例可在此Plunker中看到。为了让它工作,你将不得不安装上面提到的Chrome扩展。在密码字段中输入内容后,单击扩展哈希按钮,然后单击提交按钮,您可以看到DOM值和范围值不同。

1 个答案:

答案 0 :(得分:1)

link Bernard posted是解决此问题的正确方法。

显然这是一个Angular问题,尽管由于各种原因可能无法正式修复。然而,其中一位Google Angular开发人员编写了a fix that solves this auto fill problem.使用此polyfill工作得很好,可能是最好的解决方案,因为它是由一个实际的Angular开发人员构建的。

我不想为我的代码增加那么多额外的重量,所以我使用了这个解决方案,从同一个线程中获取。

本指令:

app.directive("autofill", function () {
return {
    require: "ngModel",
    link: function (scope, element, attrs, ngModel) {
        scope.$on("autofill-update", function() {
            ngModel.$setViewValue(element.val());
        });
     }
   };
});

然后控制器中的这一行:

$scope.$broadcast("autofill-update");

如果您遇到类似问题,请考虑使用其中一种解决方案或访问其他SO thread以了解详情。