将变量传递给AngularJS控制器,最佳做法是?


69

我是AngularJS的新手,并且喜欢到目前为止所看到的内容,尤其是模型/视图绑定。我想利用它来构建一个简单的“添加到购物篮”功能。

到目前为止,这是我的控制器:

function BasketController($scope) {
    $scope.products = [];

    $scope.AddToBasket = function (Id, name, price, image) {

        ...

    };
}

这是我的HTML:

<a ng-click="AddToBasket('237', 'Laptop', '499.95', '237.png')">Add to basket</a>

现在这可行,但是我高度怀疑这是在模型中创建新产品对象的正确方法。但是,这正是我完全缺乏AngularJS经验的地方。

如果不是这样,那么最佳实践是什么?


Answers:


65

您可以创建购物篮服务。通常在JS中,您使用对象而不是许多参数。

这是一个示例:http : //jsfiddle.net/2MbZY/

var app = angular.module('myApp', []);

app.factory('basket', function() {
    var items = [];
    var myBasketService = {};

    myBasketService.addItem = function(item) {
        items.push(item);
    };
    myBasketService.removeItem = function(item) {
        var index = items.indexOf(item);
        items.splice(index, 1);
    };
    myBasketService.items = function() {
        return items;
    };

    return myBasketService;
});

function MyCtrl($scope, basket) {
    $scope.newItem = {};
    $scope.basket = basket;    
}

7
这是有道理的-也刚刚教我如何做服务!真好 谢谢-但是,如何在没有一系列HTML输入的情况下将对象创建然后传递给控制器​​?
格雷格

取决于您的用例..您几乎可以按照任何想要的方式来做。
安德鲁·乔斯林

scope.basketProperties有什么用?
亚当·米尔斯

1
@AndyJoslin Angular如何知道如何将篮子传递给MyCtrl?
2014年

3
这种方法的一个问题是创建了一个单例实例,并且该实例对于整个应用程序都是相同的,因此对于特定的页面子控制器,您可能最终会遇到冲突或已经具有某些数据的服务。感觉就像拥有一个用于存储东西的全局对象。
2015年

86

您可以在外部div中使用ng-init

<div ng-init="param='value';">
    <div ng-controller="BasketController" >
        <label>param: {{value}}</label>
    </div>
</div>  

该参数将在您的控制器范围内可用:

function BasketController($scope) {
        console.log($scope.param);
}

没有父母,我不能这样做div吗?
Sanghyun Lee

6
是。如果愿意,可以将ng-init参数与ng-controller属性放在同一元素上。
rossipedia

2
我在与ng-controller相同的元素上使用ng-init时遇到问题。这有改变吗,还是我出了什么问题?
Rene Groeschke

16
现在不赞成使用此答案。如对此类似答案的更新所述,ngInit角度文档现在明确指出,仅被批准的用途ng-init是“为ngRepeat的特殊属性进行别名”(例如fooIndex = $index)。
达林(Daryn)

2
@Daryn的“角度方式”是将静态模板和REST API用于动态内容。要获取数据,请发出HTTP请求并通过另一个请求获取它。由于这可能是最佳做法,因此在许多情况下,页面是动态生成的。另外,如果仅使用AJAX加载数据,则SEO可能会成为问题。因此,我真的不赞成弃用该ng-init指令。而且我真的看不到这2种方法的替代方法(除了一些自定义指令(与几乎一样ng-init))。
MariusBalčytis2014年

2

我在AngularJS中不是很高级,但是我的解决方案是为您的购物车(就咖啡脚本而言)使用一个简单的JS类来扩展Array。

AngularJS的优点在于您可以通过ng-click传递“模型”对象,如下所示。

我不了解使用工厂的优势,因为我发现它不像CoffeeScript类那么漂亮。

为了可重用,我的解决方案可以在Service中进行转换。但是否则,我看不到使用工厂或服务等工具的任何优势。

class Basket extends Array
  constructor: ->

  add: (item) ->
    @push(item)

  remove: (item) ->
    index = @indexOf(item)
    @.splice(index, 1)

  contains: (item) ->
    @indexOf(item) isnt -1

  indexOf: (item) ->
    indexOf = -1
    @.forEach (stored_item, index) ->
      if (item.id is stored_item.id)
        indexOf = index
    return indexOf

然后,在控制器中对此进行初始化,并为该操作创建一个函数:

 $scope.basket = new Basket()
 $scope.addItemToBasket = (item) ->
   $scope.basket.add(item)

最后,将ng-click设置为锚点,然后将您的对象(作为JSON对象从数据库中检索出来)传递给函数:

li ng-repeat="item in items"
  a href="#" ng-click="addItemToBasket(item)" 
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.