如何将JSON数据传递给AngularJS指令

时间:2014-08-28 13:36:38

标签: javascript json angularjs

我正在学习AngularJS。我尝试创建一个名为。

的可重用组件

不幸的是,我不能用从JSON获得的数据预填充元素内的字段。 我环顾四周和网络,但无法解决它。能不能让我知道我做错了什么?

我有两个控制器。获得所有国家/地区的列表:

app.controller('MainController', ['$scope', 'Countries',
                                  function ($scope, Countries) {
  $scope.countries = Countries.query();
}]);

另一个收集了一个具体地址:

app.controller('AddressesController', ['$scope', '$routeParams', 'Address',
  function($scope, $routeParams, Address) {

    if ($routeParams.addressId) {
      $scope.senderAddress = Address.get({addressId: $routeParams.addressId});
    } else {
      $scope.senderAddress = {"id":null, "country":null, "city":null, "street":null};
    }

    $scope.adData = {"id": 1, "country": "Poland", "city": "Warsaw", "street": "Nullowska 15"};
  }]);

服务定义如下,它们似乎正常工作并提供正确的JSON:

myServices.factory('Countries', ['$resource',
                                function($resource) {
                                  return $resource('data/countries.json', {}, {
                                    query: {method:'GET'}
                                  })
                                }]);
myServices.factory('Address', ['$resource',
                               function($resource) {
                                 return $resource('data/:addressId.json', {}, {
                                   query: {method:'GET', params:{addressId:'addressId'}}
                                 })
                               }])

我有路由设置,以便它指向AddressesController:

app.config(function ($routeProvider) {
  $routeProvider
  .when('/address', {
    templateUrl: 'partials/addresses.html',
    controller: 'AddressesController'
  })
  .when('/address/:addressId', {
    templateUrl: 'partials/addresses2.html',
    controller: 'AddressesController'
  })
});

局部视图很简单,我创建了2个元素

<label> Sender </label>
<address address-data='{{senderAddress}}'></address> <!-- I tried all combinations of passing this as argument -->

<label> Receiver </label>
<address></address>

现在该指令被声明为:

app.directive("address", function () {
  return {
    restrict: "E",
    templateUrl: "/directives/address.html",
    scope: {addrData: '@senderAddress'},
    link: function(scope, element, attributes) {
      scope.adData = attributes["addressData"];
    }
  }
});

和它的模板是:

<div> 

<label> {{senderAddress}} </label> <!-- senderAddress from Addresses Controller is filled correctly -->
<div>
    <label>Country</label>
    <select>
        <option value=""></option>
        <option ng-repeat="country in countries.countries" value="{{country}}">{{country}}</option>
    </select>
</div>

<div>
    <label>City {{dto.adData.city}}</label>
    <input type="text" data-ng-model="dto.adData.city"  /> <!-- this I cannot pre-fill -->
</div>

<div>
    <label>Street{{data.adData.city}}</label>
    <input type="text" data-ng-model="dto.adData.street"> <!-- this I cannot pre-fill -->
</div>

</div>

这一切都在指令之外运作良好。但我想念一些关于如何处理指令内部范围的内容,其中数据是从JSON服务获得的。是否因为创建指令的链接时JSON数据是一个promise对象?如何处理?

PS

我也尝试过观察属性:

link: function(scope, element, attributes) {
      //scope.dto.adData = attributes["addressData"];
      attrs.$observe('addressData', function(data) {
        if (!data)
          return;
        scope.dto.adData = data;
      })
    }

即使对于静态定义的数据,它也不起作用:

app.directive("address", function () {
  return {

    controller: function($scope) {
      $scope.dto = {};
      $scope.dto.data = {"id": 1, "country": "Poland", "city": "Warsaw", "street": "Nullowska 15"};
    },

2 个答案:

答案 0 :(得分:1)

传递像这样的JSON并不是我如何做到这一点,因为它在数据绑定中是一种黑客攻击,你可能不会得到双向绑定。我使用isolate scope

您的指令将在没有把手的情况下使用,以链接范围变量:

<address address-data='senderAddress'></address>

然后您在指令定义中包含scope选项:

app.directive("address", function () {
  return {
    restrict: "E",
    templateUrl: "/directives/address.html",
    scope: {
        addressData: '='
    }
  }
});

裸等号'='告诉Angular将address-data属性中引用的父作用域变量双重绑定到子作用域变量addressData。这是通过规范化名称&#34;地址数据&#34;自动完成的。进入JS-style&#34; addressData。&#34;如果您想以不同方式命名两个范围变量,则可以改为innerAddressData: '=addressData'

如果你这样做,你根本不需要链接功能,绑定仍然有效。

答案 1 :(得分:0)

好的,我解决了,如果有人有类似的问题,可能有助于检查范围是否设置为true并检查JSON是否从字符串解析; - )。

app.directive("address", function () {
  return {
    restrict: "E",
    templateUrl: "/directives/address.html",
    scope: true, // creates its own local scope
    link: function(scope, element, attributes) {

      attributes.$observe('addressData', function(data) {
        if (!data)
          return;
        scope.dto = {};
        // works almost fine but in 2nd case data is also filled
        scope.dto.adData = angular.fromJson(data);

      })
    }
  }
});