2013-07-15 85 views
2

朋友..Angularjs范围不保留价值

为了解我如何在Angular中工作,我创建了一个简单的应用程序。此应用程序只有两个页面: 1.第一页将显示雇员表的所有行。点击特定行后,第二页将显示包含该员工详细信息的表单。

显示的第一页上的列表使用下面的代码:

<table> 
    <tr ng-repeat="employee in employees"> 
     <td>{{employee.firstname}} - {{employee. address}}</td>   
     <td><span ng-click="getSingleEmployeeDetails(employee.id)">Edit</a></td> 
    </tr> 
</table> 

我使用这两个页面相同的控制器,该控制器看起来象下面这样:

function EmployeeCtrl($scope,$http,Employee,$location,$routeParams) { 
    // Get all employee details 
    var data; 
    Employee.query().then(function(_data) { 
     $scope.employees = _data.data;    
    }); 

    // Get Single Employee Details 
    $scope.getSingleEmployeeDetails = function(id) { 
     $scope.employee = scope.employees[id]; 
     $location.path('/editemployee/' + id); 
    } 
} 

然而我面临的问题是,当代码由于某种原因被路由到/ editemployee/1
$ scope.employees失去其值。

换句话说,表单永远不会填充员工详细信息。

我在这里做错了什么?

+3

如果两个视图的控制器类型相同,则不表示它们是同一个实例。所以这个问题每次都是角度变化的路线,它会创建一个新的控制器实例,它没有任何前一个实例的信息。所以你需要使用一个服务来拥有一个你可以存储数据的单例。 – shaunhusain

+0

实际上,如果你看John Lindquist的这个例子,他似乎在改变路线时将一个控制器的$ scope应用到另一个控制器中。他如何能够做到这一点? http://www.youtube.com/watch?v=5uhZCc0j9RY&list=PLdVInYVbR-1wfi5AnAqhKwXf_PYrscUNU – runtimeZero

+0

范围继承发生,如果两个范围同时活跃,我完全推荐约翰的视频,虽然在egghead.io,是我第一次陷入Angular而且我还是回去了很多。 – shaunhusain

回答

0

这与范围界定有关。员工在实例化时加载到EmployeeCtrl中。一旦在getSingleEmployeeDetails()中执行了一个路由事件,导致不同的控制器使用不同的$范围加载。与EmployeeCtrl中的$范围分开的$ scope。解决这个问题的一个简单方法是让EmployeeCtrl处理加载/显示所有员工和单个员工而无需路由到新控制器的功能。这里的优点是它可以更轻松地共享信息,并且您不必在用户点击单个员工时重新加载单个员工信息,因为您可以更轻松地共享该信息。这意味着你不需要返回按钮导航来在单个雇员的选择之间导航。

另一种选择是让SingleEmployeeCtrl在导航时重新载入信息。亲你再次获得按钮访问权限,但是你将加载信息两次(一次用于加载完整列表,两次用于再次加载员工信息)。这还允许用户为单个员工记录添加书签,但是谁又可以书签?

+0

作为单例使用的第三个选项服务和A)为控制器中的数据返回一个承诺,或者B)在$ controller(ed)中返回。现在这是一个选择你自己的冒险。 – shaunhusain

+0

为了让事情暂时简单,我试图实现第一个结果,即让单个控制器处理事情。我如何去做这件事。从EditEmployee.html页面加载的那一刻开始,控制器将放弃其$ scope。 – runtimeZero

+0

@JamesHans可以使用ng-include指令或ng-if指令在某些变量设置为特定值时包含页面/视图。这样你就可以从路由中删除页面条目,而不是更新$ location,你只需更新你的变量。正如chubbsondubs在这里指出的那样,这“打破”了路由/深度链接。要修复路由,您还可以监听路由更改事件并手动更新控制器中的变量(虽然有点破解) – shaunhusain

0

其他人已经解释了在更改路由时创建新控制器(和$ scope)的事实。还要注意,$ promise.employees是异步填充的,当promise被解析时。可能发生的情况是getSingleEmployeeDetails()在promise解决之前被调用,所以employees数组是空的。

为了解决这个问题,我提出了一个不同的架构。

您有两个视图/页面。 Angular中的每个视图通常都有自己的控制器。模型/数据通常存储在服务中,并且检索和操作这些模型/数据的API由服务提供/公开。控制器只是将所有内容粘合在一起:它会注入它所需的服务,然后仅引用关联视图所需的模型/数据。因此,即使您的应用程序很简单,我建议您使用上述方法:一个服务(存储您的员工对象),两个控制器,两个视图。特别是,将query()调用放入您的服务中(因此在服务创建时将调用一次)并将数据存储在服务中。服务API应定义返回最终将包含所需数据(员工列表或仅一个)的承诺的函数/方法。控制器应该使用这些方法来获取所需数据的参考。

有关如何将数据存储在服务中的示例,另请参阅Should services expose their asynchronicity?

+0

感谢马克..这个架构为我清除了一些点。我现在已经包含了一项服务,但不知道如何在此服务中包含POST调用。请检查我的修改后的问题 – runtimeZero

+0

@JamesHans,将您的修改的员工对象作为参数传递给您在服务上定义的API方法。该服务方法将代表控制器调用$ http.post()。 –