【问题标题】:Pass variables to AngularJS controller, best practice?将变量传递给 AngularJS 控制器,最佳实践?
【发布时间】:2012-07-27 01:22:21
【问题描述】:

我是 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 经验的地方。

如果这不是这样做的方法,那么最佳做法是什么?

【问题讨论】:

标签: javascript javascript-framework angularjs


【解决方案1】:

您可以创建购物篮服务。通常在 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;    
}

【讨论】:

  • 说得有道理——还教我如何做服务!好的。谢谢 - 但是如何在没有一系列 HTML 输入的情况下创建然后将对象传递给控制器​​??
  • 取决于你的用例。你可以用任何你想做的方式来做。
  • scope.basketProperties 的用途是什么?
  • @AndyJoslin Angular 如何知道如何将篮子传递给 MyCtrl?
  • 这种方法的一个问题是创建了一个单例实例并且对于整个应用程序都是相同的,因此对于特定的页面子控制器,您最终可能会遇到冲突或服务已经有一些数据。感觉就像有一个全局来存储东西。
【解决方案2】:

您可以在外部 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,我不能这样做吗?
  • 是的。如果您愿意,可以将ng-init 参数与ng-controller 属性放在同一元素上。
  • 我在将 ng-init 与 ng-controller 放在同一元素上时遇到问题。这种情况发生了变化还是我做错了什么?
  • 此答案现已弃用。正如 this similar answer 的更新中所述,angular documentation for ngInit 现在明确指出 ng-init 的唯一批准用途是“为 ngRepeat 的特殊属性设置别名”(例如 fooIndex = $index)。
  • @Daryn 做事的“角度方式”是使用静态模板和 REST API 来处理动态内容。要获取数据,您发出 HTTP 请求并获取它(通过另一个请求)。由于这可能是最佳实践,因此在许多情况下页面是动态生成的。此外,如果您仅使用 AJAX 加载数据,则 SEO 可能会成为问题。所以我真的没有看到弃用 ng-init 指令的意义。而且我真的看不到有 2 种方法的替代方法(除了一些自定义指令,它与 ng-init 几乎相同)。
【解决方案3】:

我在 AngularJS 方面不是很先进,但我的解决方案是为您的购物车使用一个简单的 JS 类(在咖啡脚本的意义上),它扩展了 Array。

AngularJS 的美妙之处在于您可以使用 ng-click 传递“模型”对象,如下所示。

我不明白使用工厂的好处,因为我发现它不如 CoffeeScript 类漂亮。

我的解决方案可以转换为服务,以实现可重用的目的。但除此之外,我看不到使用工厂或服务等工具的任何优势。

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)" 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-27
    • 2013-05-13
    • 2014-12-30
    • 2014-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    相关资源
    最近更新 更多