AngularJS自定义指令与ngModel绑定无法正常工作

时间:2014-11-27 20:48:21

标签: javascript angularjs-directive

我正在尝试创建一个用于显示格式化地址的自定义指令。我已经编写了以下代码来使用新指令,但它不起作用。我的帐户控制器(未显示)工作正常,billingAddress.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>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

首先,这个例子不完整。

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

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

您可能还希望将某个功能推送到$viewChangeListeners

有关详细信息,请参阅documentation

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

&#13;
&#13;
<!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>
&#13;
&#13;
&#13;