angularjs服务中的方法未定义

时间:2014-09-19 19:22:32

标签: javascript angularjs dependency-injection angular-services

我正在阅读ng-newsletter中的2048游戏教程,但我仍然没有定义我的网格服务方法。

这是注入Grid模块及其GridService的代码模块

angular.module('Game', ['Grid'])
  .service('GameManager', ['GridService', function(GridService) {

        // create a new game
        this.newGame = function() {
            GridService.buildEmptyGameBoard();
            GridService.buildStartingPosition();
            this.reinit();
        };
  }]);

这是我的网格模块和Gridserivce以及方法角度引用未定义:

    angular.module('Grid', [])

            /**
             * GridService handles all the conditions of the board
             */
            .service('GridService', ['TileModel', function(TileModel) {

                return {
                    buildEmptyGameBoard: buildEmptyGameBoard
                }

                this.startingTileNumber = 2;



                // grid array acts the as the board and remains static
                this.grid = [];

                // tiles array acts the pieces on the board and will be dynamic
                this.tiles = [];
                this.tiles.push(new TileModel({x: 1, y: 1}, 2));
                this.tiles.push(new TileModel({x: 1, y: 2}, 2));

                // Size of the board
                this.size = 4;


                //this.buildEmptyGameBoard = function() {
                function buildEmptyGameBoard() {
                    var self = this;

                    // Initialize our grid
                    for(var x = 0; x < this.size * this.size; x++) {
                        this.grid[x] = null;
                    }

                    // Initialize our tile array 
                    // with a bunch of null objects
                    this.forEach(function(x,y) {
                        self.setCellAt({x:x, y:y}, null);
                    });

                }


        // Run a method for each element in the tiles array
                this.forEach = function(cb) {
                    var totalSize = this.size * this.size;
                    for(var i = 0; i < totalSize; i++) {
                        var pos = this._positionToCoordinates(i);
                        cb(pos.x, pos.y, this.tiles[i]);
                    }
                };

    // Convert i to x,y
            // cell position from single dimensional array
            // converts to x and y coords for pos on game board
            this._positionToCoordinates = function(i) {
                var x = i % service.size;
                    y = (i - x) / service.size;
                return {
                    x: x,
                    y: y
                };
            };


}])

    /**
     * TileModel Factory to define values for our tile directive css positions
     */
    .factory('TileModel', function() {
        var Tile = function(pos, val) {
            this.x = pos.x;
            this.y = pos.y;
            this.value = val || 2;
        };

        return Tile;
    });

Curretnly我得到了这个:错误:this.forEach不是函数

我已经能够解决此应用中的其他一些错误。所有的错误都是关于我的gridService中的方法未定义或不是函数。似乎是我的GridService无法看到的根本错误或缺失的东西。

注意:我的index.html文件中都会调用这两个文件并正确加载

2 个答案:

答案 0 :(得分:1)

  1. 你有一个早期的回复声明。这,在函数的开头:

    return {
        buildEmptyGameBoard: buildEmptyGameBoard
    }
    

    表示永远不会执行以下语句:

    this.startingTileNumber = 2;
    ...etc...
    

    Javascript在第一遍中运行声明(即buildEmptyGameBoard已声明并将被定义),但语句(即this.forEach = function(cb) {}将等待在第二次通过)。但是在第二次传递时,立即执行返回,没有其他任何操作。

    所以**将return放在函数的末尾。

  2. 服务不是控制器,不会使用new进行实例化。您的服务使用1个方法buildEmptyGameBoard返回一个对象。 this.forEach = function(cb) {}会将foreach函数附加到某个未知对象,当然对象return。所以将代码更改为:

    function buildEmptyGameBoard() { ... }
    function foreach(cb) { ... }
    ...etc...
    
    return {
        buildEmptyGameBoard: buildEmptyGameBoard,
        foreach: foreach,
        ...etc...
    };
    

答案 1 :(得分:0)

你有几个错误 - 一个是立即错误,另一个是你在修复第一个错误后发现的。

  1. &#39;这&#39;并不总是你在Javascript中的期望。调用函数不会改变上下文(你可以使用call / apply / bind之类的东西),所以请注意你的这个&#39;这个&#39;指针。使用标准JS技巧,您将获得更好的结果:

    var self = this;
    

    然后使用&#39; self&#39;无处不在,而不是这个&#39;

  2. this.forEach不存在,因为您在服务本身(此)或来电者的上下文(取决于您如何称呼您的服务)上调用它。不是指this.tiles.forEach()

  3. 您致电GridService.buildStartingPosition();但尚未定义。一旦修复了forEach,这将在此处引发异常。