0

我正在通过ng-newsletter的2048游戏教程,我被困在未定义的gridservice方法上。angularjs服务中的方法未定义

下面是代码模块注入网格模块及其设置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文件

回答

0

正确加载你有几个错误的位置 - 一个直接的一个,另一个你,只要你解决第一个发现。

  1. '这'并不总是你期望的Javascript。调用一个函数不会改变上下文(你可以使用诸如call/apply/bind之类的东西),所以看看你的'this'指针。用标准的JS技巧你会有更好的结果:

    var self = this; 
    

    然后用'self'代替'this'到处。

  2. this.forEach不存在,因为您在服务本身(this)或调用者的上下文(取决于您如何调用服务)上调用它。你的意思是this.tiles.forEach()

  3. 您致电GridService.buildStartingPosition();但您尚未定义它。一旦你解决了forEach,这会在这里抛出异常。

+0

非常感谢指针在这里我忘了自我=这项工作:所以你的代码更改。这解决了我的问题 – appthat 2014-09-19 21:02:28

1
  1. 你有一个早期return语句。这一点,在函数的开头:

    return { 
        buildEmptyGameBoard: buildEmptyGameBoard 
    } 
    

    意味着下面的语句将不会被执行:

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

    的Javascript运行在第一遍的声明(即buildEmptyGameBoard宣布和将被定义),但不是该陈述(即this.forEach = function(cb) {}将等待第二次通过)。但是在第二遍时,立即执行返回并且没有别的运行。

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

  2. 服务不是控制器,它不是用new实例化的。您的服务使用1种方法返回对象buildEmptyGameBoardthis.forEach = function(cb) {}会将foreach函数附加到某个未知对象,肯定是而不是您对象return。各地

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

非常感谢,这对理解它的流程非常有帮助。我结束了使用var self =这个工作,所以我不必将所有我的方法附加到return语句 – appthat 2014-09-19 21:00:25