在AngularJS中如何独立呈现列表的不同项

时间:2013-05-19 18:37:43

标签: javascript web-services twitter-bootstrap angularjs

我是AngularJS的新手,即使花了好几个小时,我也无法在互联网上找到以下问题的答案。

请随时建议一个更好的方法,我正在尝试下面的内容。

请参阅我的AngularJS工作进度代码:

<li ng-repeat="result in getResults()" ng-controller="resultController"> 
 <div class="name_style">
  {{result.name}}
 </div>

  <!--fetch more details for each result and set to $scope.resultDetail-->
 <div class="name_detail_style" ng-bind=getDetails(result.name) ng-controller="resultDetailController">
  {{resultDetail.image}}
  {{resultDetail.description}}
 </div>

</li>    

为简洁起见,我试图简化上述内容。

我试图将结果列表分为两部分:

  1. getResuls()进行休息服务调用以获取结果数组。

  2. 然后getDetails(result)进行另一次服务调用以获取特定结果的更多细节。

  3. 它运行得非常慢,因为AngularJS试图同时呈现名称及其细节。我希望名称在可用时立即呈现,并在getDetail()服务调用有机会获得响应时呈现详细信息。

    我无法弄清楚是否/如何使用此解决方案 How to load data asynchronously using AngularJS with SpringMVC?

    如果您需要查看控制器端代码,请告诉我。

    编辑也添加控制器代码示例。请原谅在手动重新创建以下代码的任何拼写错误。

    function resultController($scope, $http) {
        $scope.getResults = function() {
    
            $http({method: 'GET', url: resultURL=  timeout: maxTime})
                .success(function (data, status, headers, config) {
                   console.log(data);
                   $sope.result=data;     
                })
    
                .error(function (data, status, headers, config) {
                    if (status == 0) {
                        serviceTimedoutError($scope, data, status, config);
                    } else {
                        serviceFailure($scope, data, status, config);
                    }
                })
        };
    
    };
    
    
    
    function resultDetailController($scope, $http) {
        $scope.getDetails = function(result) {
              resultDetailsURL=resultDetailsUR+"/"+result  
            $http({method: 'GET', url: resultDetailsURL=  timeout: maxTime})
                .success(function (data, status, headers, config) {
                   console.log(data);
               $sope.resultDetails={"image":data["image"],"description":data["description"]};     
                })
    
                .error(function (data, status, headers, config) {
                    if (status == 0) {
                        serviceTimedoutError($scope, data, status, config);
                    } else {
                        serviceFailure($scope, data, status, config);
                    }
                })
        };
    
    };
    

2 个答案:

答案 0 :(得分:1)

我在http://plnkr.co/edit/nTI58uAkUfE3pw2yjy9q创建了一个plunk,它展示了如何使用服务和指令来实现你所谈论的结果。关键是在指令链接时,id与指令相关联。然后,detailId上的$ watch用于触发辅助呼叫。

要将此用于整个项目,您必须更新服务以使用$ http或$ resource调用从服务器获取内容。

答案 1 :(得分:1)

你不能(意思是真的不应该)在模板中引用本质上是一个AJAX调用包装函数。没关系它不是“有角度的方式”(模板不应该弄乱数据,你的ng-repeat是调用ajax函数),它会因为你正在进行AJAX调用而中断(并且每个都有一个返回数组中的元素!)为每个渲染周期!

您应该能够(并且很可能会想要)控制您何时想要从后端/ API获取信息,并且在您想要刷新它/提交任何更改之前将其保存。所以,要做的主要是改变:

<li ng-repeat="result in getResults()" ng-controller="resultController"> 

<li ng-repeat="result in myResults" ng-controller="resultController"> 

和resultController:

function resultController($scope, $http) {
    $scope.getResults = function() {

        $http({method: 'GET', url: resultURL=  timeout: maxTime})
            .success(function (data, status, headers, config) {
               console.log(data);
               $sope.result=data;     
            })

            .error(function (data, status, headers, config) {
                if (status == 0) {
                    serviceTimedoutError($scope, data, status, config);
                } else {
                    serviceFailure($scope, data, status, config);
                }
            })
    };

    $scope.myResults = $scope.getResults();

};

当控制器被实例化时,它的作用是调用AJAX请求一次

然后您可以对resultDetailController执行相同操作,但请考虑是否值得。只有当主要结果不可能改变很多(每次更改,请求重复)或细节代表大量数据时,你应该将这些调用分开,你真的需要快速显示结构,只有这样,细节。

另外,考虑只在用户“打开”时调用元素的详细信息。

编辑,对以下评论的回复

正如我所说,你应该从模板和显示中分离信息(模型,以及获取它并更新它的AJAX请求)。也就是说,你需要决定什么是最好的:

  • 您可以提前获取所有信息,然后过滤(仅过滤显示的内容)或
  • 您可以从后端获取一组经过滤的元素

在第二种情况下,您仍应控制AJAX调用的频率。例如,您可以观察过滤器变量(使用$ scope。$ watch())并在发生这种情况时调用$ http服务:

(在resultController中:)

$scope.$watch("filterString", function(){
  $scope.myResults = $scope.getResults($scope.filterString);
}

我注意到,每次在过滤器“searchbox”中输入内容时,都会产生一个新请求(这可能是过度的,甚至会导致错误的结果 - 如果“beac”请求返回之后请求“海滩”,例如)。一种可能的解决方案是在您键入时实现覆盖前一个的超时(搜索仅在您停止键入后的.5秒内启动)

$scope.$watch("filterString", function(){
  $scope.getResultsTimeout.cancel();
  $scope.getResultsTimeout = $timeout(
    function(){
      $scope.myResults = $scope.getResults($scope.filterString);
    },
    500);
}