AngularJS-在页面之间传递数据


67

我是AngularJS入门者。我正在尝试从发送数据:

  • A页:范列表页面

  • 网页B:Van更新页面。

当用户单击货车的更新链接时,我正在调用控制器并在控制器中检索货车详细信息。但是,我无法使用同一控制器将货车详细信息分配给页面B(货车更新页面)...错误"Cannot set property 'vanNumber' of undefined"

*** Page A: Van List ****

<form name="listVanForm" >
   <table>
   <tr> <td ng-controller="VanUpdateCtrl"><a href="#/van-update" ng-click="prePopulateForm(row.members.vanNumber.value )" class="btn btn-small btn-primary">update</a></td> </tr>
   </table>
</form>

*** Page B: Van Update ****

  <div class="container">
        <h2>Edit Van </h2>
    
        <form name="updateVanForm" novalidate="novalidate" class="form-horizontal" ng-submit="updateCard(formData)">
            <div class="control-group">
                <label class="control-label" >Van Number:</label>
    
                <div class="controls">
                    <input type="text" id="vanNumber" ng-model="formData.vanNumber" placeholder=""/>
                </div>
            </div>
        </form>
     </div>

*** VanUpdateCtrl **

   app.controller('VanUpdateCtrl', ['$scope', 'VanUpdateFactory', '$location',
                                      function ($scope, VanUpdateFactory, $location) {
    
        //callback for ng-init 'populateDD':    
        $scope.prePopulateForm = function (cardNoParam m) {
            
            alert('cardNo = '+cardNoParam);
            
            $scope.formData.cardNumber=cardNoParam;}
    }
    
So, $scope.formData.cardNumber OR $scope.formData in the destination page is not recognised.

您在页面上有多少个控制器?也许我理解您的情况不对,您能否发布所有涉及的控制器。
2014年

所以我猜路由#/ van-update在$ routeProvider中有关联的VanUpdateCtrl,对吗?
2014年

3
如此一来,您就知道每次通过ng-controller或通过将其关联到路由来引用控制器时,它都是该控制器的新实例。就页面之间使用相同的$ scope而言,您不能共享控制器。
2014年

是的,那很好。问题是当首次显示Van Update屏幕时,我想使用相同的控制器用van列表中的详细信息预先填充它。用户完成更改后,我可以成功处理表单提交。它只是预填充一个有问题的表格。
巨型

确实,这意味着我必须使用2个控制器和一个服务。使用一个控制器在服务中设置货车详细信息,然后在第二个控制器中进行检索。可以在更新详细信息页面上使用ng-init函数。
2014年

Answers:


125

您需要创建一个服务,以便能够在控制器之间共享数据。

app.factory('myService', function() {
 var savedData = {}
 function set(data) {
   savedData = data;
 }
 function get() {
  return savedData;
 }

 return {
  set: set,
  get: get
 }

});

在控制器A中:

myService.set(yourSharedData);

在控制器B中:

$scope.desiredLocation = myService.get();

请记住通过将myService作为参数传递到控制器中。


13
没为我工作。在下一页上,该服务似乎已重新创建,并且get()返回空。
hadaytullah

2
@AlexisGamarra如果您阅读注释,您将了解到在两个不同的页面中不能有相同的控制器,每个控制器都是一个新实例。
2015年

3
效果很好。但是,如果我通过按ctrl + f5刷新第二页,服务将重置,因此该页将变为空白。您如何缓存最后的set数据,以便刷新带有控制器B的第二页时不会丢失最后的数据?
Neel 2015年

3
@blackops_programmer,可以使用$ cookies或localStorage。
2015年

7
是的,使用sessionStorage.setItem('key','value'); 在您的服务中进行存储,并在sessionStorage.getItem('key')中进行检索。
2016年

8

您应该做的是创建一个在控制器之间共享数据的服务。

不错的教程https://www.youtube.com/watch?v=HXpHV5gWgyk


我想澄清一下-如果在新标签页中打开第二页,是否可以使用?我要重试,可能是在最初的测试中,因为它对我不起作用,所以我没有正确实现它
Naomi

8

如果只需要在视图/作用域/控制器之间共享数据,最简单的方法是将其存储在$ rootScope中。但是,如果需要共享功能,最好定义一个服务来实现。


3
@杨Z 感谢您分享此选项。要强调。您可以将数据存储到$ rootScope,然后从另一个视图检索它。但是,与使用根/全局作用域的任何快速解决方案一样,几乎总是有更好的解决方案。该角度解决这个问题将通过共享服务来传递您的数据。
亚历克斯·约翰逊

取决于数据。如果您设置var,这可能很糟糕,它将导致摘要超过rootScope
Tatarin

使用$ rootScope在页面之间共享数据是一个糟糕的主意。是的,这是最简单的方法,但是它也是将来最会破坏您的方法。它是全局数据,当该数据开始被不知道已定义变量的第三页意外突变时,它可能会再次咬住您。它污染$ rootScope,使摘要周期变慢。有很多理由从来没有使用$ rootScope来共享数据,就像有很多理由从来没有使用传统编程语言中的全局变量一样。
iamtheddrman

@iamtheddrman关于污染rootScope的要点。我100%同意您的意见,但是您是否有任何参考资料会导致摘要循环变慢?
losmescaleros

当然:airpair.com/angularjs/posts/... medium.com/developers-writing/...一些性能损失也来自观察家触发其他观察家在消化周期的可能性,使得它需要更长的时间来解决回落时外力对其作用。较小的$ rootScope以及正确使用服务和控制器可以缓解此问题,从而使应用程序更快。
iamtheddrman

-1
app.factory('persistObject', function () {

        var persistObject = [];

        function set(objectName, data) {
            persistObject[objectName] = data;
        }
        function get(objectName) {
            return persistObject[objectName];
        }

        return {
            set: set,
            get: get
        }
    });

像这样填充数据

persistObject.set('objectName', data); 

像这样获取对象数据

persistObject.get('objectName'); 

就像您重新发布答案一样。
YATO
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.