带有 ngModel 绑定的 AngularJS 自定义指令不起作用

AngularJS custom directive with ngModel binding not working

本文关键字:自定义 指令 不起作用 AngularJS ngModel 绑定 带有      更新时间:2023-09-26

我正在尝试创建一个自定义指令来显示格式化的地址。我已经编写了以下代码来使用 new 指令,但它不起作用。我的帐户控制器(未显示)工作正常,并且计费地址.Line1 显示正确。但是,我的地址指令不会呈现任何内容。

我已经在我的 html 中包含指令代码,尽管我希望将其移动到单独的 .js 文件中以供重用。有人可以解释我做错了什么吗?

<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
  <script type="text/javascript" src="ng-address.js"></script>
  <script type="text/javascript" src="app.js"></script>
  <script type="text/javascript">
    (function() {
      var app = angular.module('ng-directives', []);
      app.directive("ngAddress", function() {
        return {
          restrict: 'E',
          scope: {
            address: '=ngModel'
          },
          template: "<div>{{address.Line1}}</br><span>{{address.Line1}}</br></span>{{address.city}}, {{address.state}} {{address.postCode}}</div>"
        };
      });
    })();
  </script>
</head>
<body class="container" ng-controller="AccountController as account">
  <div>{{account.model.billingAddress.line1}}</div>
  <ng-address ng-model="account.model.billingAddress"></ng-address>
</body>
</html>

首先,该示例不完整。

  • 我将角度模块更改为myApp
  • 我添加了一个控制器AccountController
  • 在ng-controller中使用as不起作用。我不确定这是否应该有效,但我从不使用它。

该指令的主要问题是ng-model使用不当。您应该将其传递给require,而不是范围。然后将其传递给link函数,在该函数中实现$render函数。

您可能还想将函数推送到 $viewChangeListeners

有关更多详细信息,请参阅文档。

最后模板包含</br>,这是无效的。

<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
  <script type="text/javascript">
    (function() {
      var app = angular.module('myApp', []);
      app.controller('AccountController', function($scope) {
        $scope.model = {
          billingAddress: {
            line1: 'somewhere far far away',
            city: 'Dark side of the moon',
            state: 'Top secret',
            postCode: '1337XD'
          }
        };
      });
      app.directive("ngAddress", function() {
        return {
          restrict: 'E',
          require: '?ngModel',
          template: "<div>{{address.line1}}<br><span>{{address.line1}}<br></span>{{address.city}}, {{address.state}} {{address.postCode}}</div>",
          link: function(scope, element, attrs, ngModel) {
                ngModel.$render = function() {
              scope.address = ngModel.$modelValue;
            };
          }
        };
      });
    })();
  </script>
</head>
<body class="container" ng-controller="AccountController">
  <input class="form-control" ng-model="model.billingAddress.line1"/>
  <input class="form-control" ng-model="model.billingAddress.city"/>
  <input class="form-control" ng-model="model.billingAddress.state"/>
  <input class="form-control" ng-model="model.billingAddress.postCode"/>
  <ng-address ng-model="model.billingAddress"></ng-address>
</body>
</html>