重新加载 ng-repeat 数据失败,我做错了啥?

Posted

技术标签:

【中文标题】重新加载 ng-repeat 数据失败,我做错了啥?【英文标题】:Reloading ng-repeat data failed, what did I do wrong?重新加载 ng-repeat 数据失败,我做错了什么? 【发布时间】:2015-06-02 02:31:34 【问题描述】:

我喜欢在处理一些数据后重新加载ng-repeat 元素,但它失败了。我想知道我做错了什么。

所以我从“iframe.php”加载一些数据然后将数据插入到jquery的不可见div标签中以将数据(html格式)映射为json格式并将json数据保存到一个名为tableObject 的变量。然后我将使用scope.$apply(scope.showCards) 将数据推送到我的$scope.cards

这是我的代码:

var app = angular.module('rabbit', ['ngMaterial', 'ngMessages', 'ngMdIcons']),
    apiURL = 'iframe.php',
    tableObject = [];

$.ajax(
  url: "iframe.php",
  crossDomain: true,
  dataType: "html",
  success: function(data) 
    var json = data.substring(data.indexOf('<tr class = "pfrow2">') - 21);
    json = json.substring(0,json.indexOf('<td style="margin-top: 20px" colspan="2">'));
    json = json.substring(0,json.lastIndexOf('</td>') + 5);
    function widthChange() 
      if (json.indexOf('&width=130') != -1) 
        json = json.replace('&width=130','&width=300');
        widthChange();
       else 
        // console.log(json);
        $('#json').html(json);
        var headers = ["name","kind","type","age","size","thumb","link"];
        tableObject = $("#json tr").map(function(i)
          var row = ;
          $(this).find('td').each(function(i)
            var rowName = headers[i];
            row[rowName] = $(this).text().trim();
          );
          $(this).find('td.legacy img').each(function()
            var rowName = headers[5];
            row[rowName] = $(this).attr('src');
          );
          $(this).find('td.legacy a').each(function()
            var rowName = headers[6];
            row[rowName] = $(this).attr('href');
          );
          return row;
        ).get();
        console.table(tableObject);
        $('#json').html('');
        var scope = angular.element($('#content')).scope();
        scope.$apply(scope.showCards);
      
    
    widthChange();
  ,
  error: function() 
    console.log('error');
  ,
);

app.controller('cardCtrl', function ($scope, $log, $mdDialog) 
  var showCards = function() 
    $scope.cards.push(tableObject);
  ;
  $scope.cards = tableObject;
);

这是 HTML 中的 ng-repeat 元素:

  <div id="content" layout-sm="col" layout="row" layout-wrap ng-controller="cardCtrl">
    <md-card ng-repeat="card in cards" class="noselect" md-ink-ripple>
      <img src="card.thumb" >
      <h2>card.name</h2>
      <p>card.type</p>
      <p>card.age</p>
      <p>card.size</p>
      <a href="card.link"></a>
    </md-card>
  </div>

【问题讨论】:

你有没有考虑过使用 $http 模块而不是 jquery 的 $.ajax?因为那将消除您使用 scope.$apply. 的需要 @TiagoMartins 是的,我最初使用 $http 但后来由于一些注入错误而取消了代码。我怀疑 $http 从 $.ajax 返回一个不同的 (html) 对象,这使得我的代码无法操作。如果 null 的解决方案不适合我,我可以上传代码。 @TiagoMartins null 的解决方案有效。 【参考方案1】:

很难看出到底出了什么问题,但我猜tableObject 被重新分配给不同的数组实例:控制器总是绑定你全局声明的空数组(这很邪恶)。

您可以做几件事。最简单的是将 jquery 语句重构为控制器可以调用的工厂方法。

app.factory('myAjaxThingy', function($q) 
  return function() 

      // Create a defer to async promise the consumer a result
      var defer = $q.defer();

      $.ajax( 
        /* ... */
          success: function(data) 

            // Construct the array here

            var tableObject;

            /* ... */
            /* all that parsing magic goes here */
            /* ... */            

            // Resolve the promise
            // Note: no whacky angular.element().scope() and no scope.aplly()
            defer.resolve(tableObject);
          
      );

      // Return the promise object
      return defer.promise;
  ;
);

app.controller('MyController', function(myAjaxThingy) 

  myAjaxThingy().then(function(result) 
    $scope.cards = result;
  );

);

这样,您甚至可以在需要时重新执行调用。另请注意,angular 有一个相当不错的$http 服务,可以与$.ajax 做同样的事情。

【讨论】:

我最初确实使用 $http 方法创建了一个工厂,但尝试失败。我现在将尝试使用 $q,看看效果如何。 哇,你是了不起的 Angular 之神。

以上是关于重新加载 ng-repeat 数据失败,我做错了啥?的主要内容,如果未能解决你的问题,请参考以下文章

我不知道我做错了啥[关闭]

JavaScript 中的 HTML5 音频:我做错了啥?

核心数据多线程——我做错了啥

Angular 6 - 从 observable 获取数据我做错了啥?

QTreeView 的 QAbstractItemModel:我做错了啥?

这个 MERGE / INSERT 查询我做错了啥?