创建工厂以将数据从指令传递到AngularJS中的控制器

时间:2014-03-25 22:21:18

标签: javascript angularjs

我有一个指令,在$ http调用之后为ng-repeat列表的每个元素返回一个数组。

看起来像这样:

    var app = angular.module('myApp');


app.directive('release', ['musicInfoService', 'dataService',
  function(musicInfoService, dataService) {

    return {
      restrict: 'E',
      scope: {
        release: '=',
        artist: '='
      },
      template: '<div class="release">' +
        '<div class="wrapper"><img class="img-responsive" ng-src="{{imageSrc}}"/><div id="text" ng-click="getVersions(release)"></div></div>{{release.title | characters:45}}' +
        '<ul><li ng-repeat="version in defaultFormat">{{version.format}}</li><li ng-show="basicFormat">{{basicFormat}}</li></ul>'+
        '</div>',
      replace: false,
      link: function(scope, elem, attr) {
        var defaultImage = 'img/record-default.png';
        scope.imageSrc = defaultImage;
        musicInfoService.getAlbumInfo(scope.artist.name, scope.release.title)
          .success(function(data) {
            if (data.error) return;

            var image = data.album.image[2],
              imageUrl = defaultImage;

            if (image['#text'] !== '') {
              imageUrl = image['#text'];
            }

            scope.imageSrc = imageUrl;
          });
        var defaultFormat = scope.release.format;
        musicInfoService.getReleaseVersions(scope.release.id)
        .success(function(data) {
            if (data.error) return;

            var format = data.versions,
              formats = scope.release.format;

            if (format !== '') {
              formats = format;
            }

            scope.defaultFormat = formats;
            dataService.setItems(scope.defaultFormat);
          })
          .error(function($scope) {
            scope.basicFormat = scope.release.format;
            dataService.setItems(scope.basicFormat);
         });
      }
    };
  }
]);

app.factory('dataService', [function($scope){
   var _items= "";
   return { 
          setItems:function(value){
             _items=value;
          },
          getItems:function(){
             return _items;
          }
  };
}]);

现在,当点击一个元素时,我需要能够将这些数据传递给div(在指令之外)。

<div class="infinite" infinite-scroll="loadDetails()">
      <div ng-repeat="row in main.rows">
        <div class="row">
          <div class="col-xs-3 col-md-3" ng-repeat="release in row | filter:main.album" ng-click="main.releaseClicked=release;" ng-class="{'selected':main.releaseClicked==release}">
            <release release="release" artist="main.artist"></release> 
          </div>
        </div>
        <div class="row" ng-repeat="release in row" ng-if="main.releaseClicked==release">
          <div id="collapse" ng-controller="VersionController" class="col-md-12 col-xs-12">
            <div class="inner">
              <ul>
                <li>{{release.title}}</li>
                <li ng-repeat="version in versions">
                  {{version.format}}
                </li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>

因此,在ng-click =&#34; main.releaseClicked = release;中,将显示第二行,并且应使用来自VersionController的数据填充ng-repeat。

我在另一个问题中得知,一旦从服务器下来,我应该将数据设置在一个变量中,并在调用函数VersionController后得到它(因为它将是每个元素点击的不同数据),但到目前为止,我无法做到。

我试过这样,但是我从每个项目中显示最后一项的结果,这意味着存储了最后一个元素的数据,但是单击每个项目时变量未更新

在我的指令之后:

app.factory('dataService', [function($scope){
   var _items= "";
   return { 
          setItems:function(value){
             _items=value;
          },
          getItems:function(){
             return _items;
          }
  };
}]);

然后在script.js的末尾

function VersionController($scope, dataService) {
  $scope.versions = dataService.getItems();
  console.log($scope.versions);
}

这里是完整的文件:

    (function(){

var app = angular.module('myApp', ['chieffancypants.loadingBar', 'ngResource', 'ui.bootstrap', 'truncate']);

var Ctrl = function(musicInfoService) {
  this.musicInfoService = musicInfoService;
};

Ctrl.prototype.onArtistChange = function(){
  var artist = this.artist;

  if(angular.isUndefined(artist)) return;

  var pos = artist.name.toLowerCase().indexOf(', the');

  if (pos != -1) {
    artist.name = 'The ' + artist.name.slice(0, pos);
  }
};

Ctrl.prototype.reset = function(){
  this.sliding = false;
  this.name = undefined;
};

Ctrl.prototype.search = function(name) {
  var _this = this;

  if (name) {
    _this.musicInfoService.searchArtists(name)
    .success(function(data) {
      _this.clicked = false;
      _this.results = data.results;
    });
  }
};

Ctrl.prototype.getDetails = function(id) {
  var _this = this;

  _this.musicInfoService.getDetails(id)
  .then(function(data){
    _this.artist = data.artist;
    _this.releases = data.releases;
    _this.onArtistChange();

   _this.getRows = function(array) {
    var rows = [];
    var i,j,temparray,chunk = 4;
    for (i=0,j=array.length; i<j; i+=chunk) {
        temparray = array.slice(i,i+chunk);

        rows.push(temparray);
    }
    return rows;
    };
    _this.rows = _this.getRows(data.releases);
  });

  _this.clicked = true;
  _this.sliding = true;
};

Ctrl.$inject = ['musicInfoService'];

app.controller('Ctrl', Ctrl);



}());

function VersionController($scope, dataService) {
  $scope.versions = dataService.getItems();
  console.log($scope.versions);
}

另外,在指令I中注入dataService,所以问题不应该来自那里。

任何指针?

编辑:此处a Plunker。请注意,在示例中,发布版本显示在发布标题下,但我想要做的只是在单击发布项目时显示它们(在下面的框中)。

0 个答案:

没有答案