Angularjs范围不保留值

Angularjs范围不保留值,angularjs,Angularjs,朋友们 为了理解Angular中路由的工作原理,我创建了一个简单的应用程序。此应用程序只有两个页面: 1.第一页将显示employee表的所有行。单击特定行后,第二个页面将显示一个包含该员工详细信息的表单 第一页上显示的列表使用以下代码: <table> <tr ng-repeat="employee in employees"> <td>{{employee.firstname}} - {{employee. address}}</

朋友们

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

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

<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>
然而,我面临的问题是,当代码被路由到/editemployee/1时
由于某种原因,$scope.employees失去了它的值

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


我做错了什么?

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


另一个选项是让SingleEmployeeCtrl在导航时重新加载信息。其优点是您可以再次访问“返回”按钮,但缺点是您可以加载两次信息(一次用于加载完整列表,两次用于再次加载员工信息)。这也允许用户为单个员工记录添加书签,但是谁还会为这些记录添加书签呢?

其他人已经解释了这样一个事实,即当您更改路由时,会创建一个新的控制器(和$scope)。还请注意,在解决承诺时,$scope.employees是异步填充的。可能发生的情况是,在解析承诺之前调用了getSingleEmployeeDetails(),因此
employees
数组为空

为了解决这个问题,我建议采用不同的体系结构

您有两个视图/页面。角度视图中的每个视图通常都有自己的控制器。模型/数据通常存储在服务中,用于检索和操作这些模型/数据的API由服务提供/公开。控制器只是将所有东西粘在一起:它注入它需要的服务,然后只引用关联视图需要的模型/数据

因此,即使你的应用程序很简单,我还是建议使用上述方法:一个服务(存储员工对象)、两个控制器、两个视图。特别是,将
query()
调用放入您的服务中(这样在创建服务时它将被调用一次),并将数据存储在服务中。服务API应该定义函数/方法,这些函数/方法返回最终将包含所需数据的承诺(员工列表,或仅一个)。控制器应使用这些方法获取所需数据的引用


另请参见如何在服务中存储数据的示例。

如果两个视图的控制器类型相同,并不意味着它们是相同的实例。因此,问题是每次角度改变路线时,它都会创建一个控制器的新实例,而该实例不包含前一个实例所拥有的任何信息。因此,您需要使用一个服务来拥有一个可以存储数据的单例。实际上,如果您查看John Lindquist的示例,他似乎在更改路由时将一个控制器的$scope用于另一个控制器。他是怎么做到的?如果两个作用域同时处于活动状态,则会发生作用域继承。我完全推荐John的视频,尽管在egghead.io,这是我第一次接触Angular,我仍然会回顾很多。理解作用域继承的细节实际上只需要很好地理解原型继承(特别是如果你来自一个类(y))继承模型)。简而言之,如果您从祖先继承了一个属性,那么当某个对象试图读取您的属性时,它将从您的祖先读取,但是如果直接在您的实例上赋值,它将不再指望祖先获取值。这意味着事情可能会以奇怪的方式“中断”(第一次工作)。第三个选项服务用作单例,A)返回数据承诺或B)控制器中的$watch(ed)。现在是一个选择你自己的冒险。为了让事情暂时保持简单,我正在尝试实现第一个结果,即让一个控制器来处理事情。我该怎么做呢。由于EditEmployee.html页面一加载,控制器就失去了$scope。@JamesHans当某些变量设置为特定值时,您可以使用ng include指令或ng if指令来包含页面/视图。这样,您将从路由中删除页面条目,而不是更新$location,您只需更新变量即可。正如chubbsondubs在这里指出的那样,这“打破”了路由/深度链接。要修复路由,您还可以侦听路由更改事件并手动更新控制器中的变量(尽管有点黑客),同时执行ng include。我试图描述的是将EditEmployee.html中的标记与控制器已经使用的html合并到同一个文件中。因此,您可以轻松地在父div上使用ng show=“selectedEmployee!=null”来显示/隐藏它。当然,当用户单击员工表时,设置selectedEmployee。深度链接可能并不重要。很多时候不是这样的。谢谢你,马克。。这种架构为我澄清了一些问题。我现在已经包括了一项服务,但不知道如何在这项服务中包括POST CALL。请检查我的修改question@Jam
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);
    }   
}