如何在Angular JS中在两个HTML页面之间共享控制器数据

20 浏览
0 Comments

如何在Angular JS中在两个HTML页面之间共享控制器数据

我有一个基本的控制器,用来显示我的产品,

App.controller('ProductCtrl',function($scope,$productFactory){
     $productFactory.get().success(function(data){
           $scope.products = data;
     });
});

在我的视图中,我用一个列表显示这些产品

  • {{product.name}}

我想做的是当有人点击产品名称时,我有另一个名为购物车的视图,将该产品添加到其中。

 
  • //点击后添加一个产品
  • //点击后添加第二个产品

所以我的问题是,如何将第一个控制器中点击的产品传递到第二个控制器中?我认为购物车也应该是一个控制器。

我使用指令来处理点击事件。我感觉我应该使用服务来实现上述功能,只是不知道如何实现?因为购物车将是预定义数量的产品,可以是5/10,这取决于用户在哪个页面。所以我想保持这个通用性。

更新:

我创建了一个广播服务,在第二个控制器中接收它。现在的问题是如何更新DOM?因为我的产品列表很硬编码。

0
0 Comments

在AngularJS中如何在两个HTML页面之间共享控制器数据?

问题的出现原因是怎样将第一个控制器中点击的产品传递给第二个控制器?

解决方法是在点击事件中调用一个方法,该方法调用广播:

$rootScope.$broadcast('SOME_TAG', 'your value');

而第二个控制器将监听这个标签,如下所示:

$scope.$on('SOME_TAG', function(response) {
      // ....
})

由于我们不能将$scope注入到服务中,因此没有类似单例$scope的东西。

但是我们可以注入$rootScope。因此,如果将值存储在服务中,可以在服务主体中运行$rootScope.$broadcast('SOME_TAG', 'your value');(有关服务的描述,请参见说明)

app.service('productService',  function($rootScope) {/*....*/}

请查看关于$broadcast$emit的好文章

是的,这个方法非常好用,我正在使用工厂模式。我只有一个问题,我在每次点击产品时都会在新的控制器中获取到数据。现在我该如何在DOM中更新它?因为我已经有了固定边框的5个产品列表,所以每个产品都需要放在其中一个边框中。

- 你找到答案了吗?这似乎是一个显而易见的问题,但我无法在任何地方找到答案。我希望一个控制器可以更改某个值。当该应用程序值更改时,任何其他监听控制器都应相应地更新自己。找不到答案。

对你的问题的答案基于你的控制器结构:是否平行或父子。 $rootScope.$broadcast 通知所有具有平行结构(即相同级别)的控制器。

非常感谢您的回复。是否可以使用$watch来实现这个?顺便说一句,我的控制器是平行的,我已经使用了你的方法使其工作。对我来说,每当我尝试添加$watch(即使是$rootScope),与第二个控制器关联的方法只会在第一次(第二个控制器的初始化)时触发。谢谢。

如果值存在于$rootScope级别,我们可以使用$watch。否则,只有广播可以通知其他控制器。顺便说一下,如果其他程序员在你的代码中看到广播,那么逻辑是清楚的,你试图做的是“广播事件”。无论如何,根据我的经验,使用$rootscope来进行$watch不是一个好的实践。关于“只触发一次”的问题:查看这个示例:plnkr.co/edit/5zqkj7iYloeHYkzK1Prt?p=preview你会得到旧值和新值。确保每次得到的新值与旧值不相等。

到底哪里出了问题?此外,如果某些用例不起作用,这并不意味着要投票反对。投票反对意味着从你的角度来看,答案是错误的。

首先,我认为我必须回答你的问题,"$scope.$on"不执行,对于误解,我更新了你的问题,请检查一下并理解我的不成熟。

如果用户刷新页面会怎样?那么getProducts()将会返回空值!(你不能告诉所有用户不要刷新,对吧?)

这与$broadcast有什么关系?在页面刷新时,您再次调用app.run,即整个Angular引擎。:)

当您在第二个控制器中时,第二个控制器的模板将被加载。现在你有了$broadcast的值,一切都很好。此时用户刷新页面!现在没有值设置为广播!

好吧,这是另外一个故事,当你使用路由时,广播应该以不同的方式工作,这与SO的问题无关。

我曾经在一个被公众使用的应用中工作过。遇到类似的问题。因此,我认为使用$localStrorage会很方便。

0
0 Comments

如何在AngularJS中的两个HTML页面之间共享控制器数据

在AngularJS中,我们可以使用$rootScope来共享控制器之间的属性。$rootScope是一个全局的作用域对象,所有其他作用域都是它的子作用域。虽然使用$rootScope可以实现数据共享,但是最好的方式是使用服务。

以下是使用$rootScope共享数据的解决方法:

1.在模块中定义控制器并注入$rootScope:

var app = angular.module('mymodule', []);
app.controller('Ctrl1', ['$scope', '$rootScope',
  function($scope, $rootScope) {
    $rootScope.showBanner = true;
}]);
app.controller('Ctrl2', ['$scope', '$rootScope',
  function($scope, $rootScope) {
    $rootScope.showBanner = false;
}]);

2.在模板中使用$rootScope的属性:

尽量避免使用$rootScope,因为它是一个全局作用域对象,任何人都可以修改它,使程序状态变得不可预测。在控制器之间共享数据的更好方式是使用服务或工厂。

如果用户刷新页面,服务将无法返回任何值。在这种情况下,使用$rootScope是更可行的选择,因为它不容易出错。

总之,虽然$rootScope可以用来共享控制器数据,但是最好的方式是使用服务来实现数据共享,以避免全局作用域带来的潜在问题。

0
0 Comments

在AngularJS中,如果我们想要在两个HTML页面之间共享控制器数据,可以使用服务(service)来实现。具体的实现方法如下:

首先,我们需要定义一个产品服务(productService),将其作为一个工厂(factory)来创建:

app.factory('productService', function() {
  var productList = [];
  var addProduct = function(newObj) {
      productList.push(newObj);
  };
  var getProducts = function(){
      return productList;
  };
  return {
    addProduct: addProduct,
    getProducts: getProducts
  };
});

然后,我们将这个服务注入到两个控制器中。

在`ProductController`中,我们定义一个添加选中对象到数组中的动作:

app.controller('ProductController', function($scope, productService) {
    $scope.callToAddToProductList = function(currObj){
        productService.addProduct(currObj);
    };
});

在`CartController`中,我们通过服务获取产品列表:

app.controller('CartController', function($scope, productService) {
    $scope.products = productService.getProducts();
});

如果我们希望`CartController`在调用`getProducts()`时自动更新,可以在Maxim Shoustin的答案中添加广播(broadcast),并在`$on`函数中调用`getProducts()`来更新`CartCtrl`的作用域(scope)。

为了使这个设置对我有效,我需要在`app.service('productService', function() { });`中添加`return`,以便可以在其他控制器中使用这些属性和方法。

如果除了产品列表之外,还有另一个对象需要在两个控制器之间共享,可以创建新的方法来处理这个对象,例如`addNewObj`和`getNewObj`。或者也可以考虑扩展这些方法,使其不仅仅在内存中保存数据,还可以更持久地保存数据(例如通过`$http`调用保存到服务器)。

如果有两个`ProductController`和两个`CartController`,那么添加的元素会被同时添加到两个控制器中。至于这种情况下的解决方案,请进入链接提供的聊天室讨论。

有人问到,如果用户刷新页面会发生什么?那时`getProducts()`将返回空,因为这个解决方案只是在内存中传递数据,并没有持久化。如果希望数据持久化,可以考虑将数据保存到本地存储或者在服务函数中添加更持久的解决方案。

还某些情况下,在他将`.service`改为`.factory`之后,这个解决方案才有效。实际上,应该使用工厂(factory)而不是服务(service),因为我是返回了一个包含get/add函数的对象字面量。服务(service)和工厂(factory)是有区别的,如果使用服务(service),就需要直接在`this`上设置这些函数。我已经将答案中的代码进行了更新。

0