我有一个c#背景,我开始探索Angular JS。我将我的工厂类/对象基于这篇文章:https://medium.com/opinionated-angularjs/2e6a067c73bc
所以我有2个工厂类,但我想在另一个工厂内引用一个工厂的实例。但是,由于java脚本不是类型化语言,因此在“编译”时,其他工厂内的某个工厂的属性和方法不可用。
检查这个小提琴:http://jsfiddle.net/Frinkahedron/PxdSP/1337/ var myApp = angular.module('myApp',[]);
myApp.factory('grid', function () {
// Constructor, with parameters
function grid(sizeX, sizeY, gridName) {
//public properties
this.cells = new Array();
this.name = gridName;
//load cells
var numCells = sizeX * sizeY;
for (var i = 0; i < numCells; i++) {
this.cells.push(i);
}
}
//Return the constructor function
return grid;
});
myApp.factory('game', ['grid', function (_grid_) {
//private reference for the grid factory
var grid = _grid_;
function game(){
//do some setup with grid reference
this.gridName = "Grid : " + grid.gridName;
};
game.prototype.isWinner = function () {
//iterate cells to see if game has been won
//this loop doesn't cause "compile" errors
for (var c in grid.cells){
//do something with each cell in the grid
}
//this loop doesn't work due to grid.cells.length
//because there is no length property of undefined
//uncomment to see it blow up
//for(var i=0; i< grid.cells.length;i++){}
return true;
};
return game;
}]);
function MyCtrl($scope, grid, game) {
var g = new grid(3, 3, "Test Grid");
$scope.myLength = g.cells.length;
$scope.myGridName = g.name;
//how to pass the grid reference to the game?
//if i pass the grid in the constructor of the game,
//it still doesn't work because javascript doesn't have types
//and the grid.cells (and other grid property references) are
//problematic
var a = new game();
$scope.myGameName = a.gridName;
$scope.myWinner = a.isWinner();
}
Grid工厂按预期工作,但我无法弄清楚如何在Game工厂中引用网格实例。我已经尝试将网格“对象”传递给Game构造函数,但由于java脚本不是类型化语言,因此游戏工厂中的网格属性/方法未定义。
答案 0 :(得分:0)
在角度中,工厂应该返回一个物体。你返回一个函数。
您似乎希望提供商能够配置您的网格而不是工厂。
示例(未经测试):
myApp.provider('grid', function () {
'use strict';
var x, y, name;
var Grid = function () {
// Grid instance has access to x, y and name
};
this.setX = function (newx) {
x = newx;
};
this.sety = function (newy) {
y = newy;
};
this.setname = function (n) {
name = n;
};
this.$get = function () {
return new Grid();
};
});
使用此提供商,您可以:
myApp.configure(['gridProvider',
function (gridProvider) {
'use strict';
gridProvider.setx(100);
gridProvider.sety(100);
gridProvider.setname('name');
}
]);
myApp.controller('myCtrl',
['grid', '$scope',
function (grid, $scope) {
'use strict';
// grid is now an instance of 'Grid'
}
]);
修改
myApp.factory('Grid', function () {
'use strict';
function Grid(sizeX, sizeY, gridName) {
var
i, numCells = sizeX * sizeY;
this.cells = [];
this.name = gridName;
for (i = 0; i < numCells; i++) {
this.cells.push(i);
}
}
return Grid;
});
myApp.factory('Game', function () {
'use strict';
function Game(grid){
this.gridName = "Grid : " + grid.name;
};
Game.prototype = {
isWinner: function () {
var i, l;
for (i = 0, l = grid.cells.length; i < l; i++) {
//do something with each cell in the grid
}
return true;
}
};
return Game;
});
myApp.controller('myCtrl', ['$scope', 'Grid', 'Game',
function ($scope, Grid, Game) {
'use strict';
var
grid = new Grid(3, 3, "Test Grid"),
game = new Game(grid);
$scope.myLength = grid.cells.length;
$scope.myGridName = grid.name;
$scope.myGameName = game.gridName;
$scope.myWinner = game.isWinner();
}]);
答案 1 :(得分:0)
我找到了一个解决方案,但这并不理想:http://jsfiddle.net/Frinkahedron/LJqz7/2/
我现在将Grid的参数传递给Game函数并在Grid中创建Game。
myApp.factory('game', ['grid', function (_grid_) {
var grid = _grid_;
//TODO: instead of passing the parameters for the grid
//into the game, I would prefer to pass the grid "class"
//But that doesn't seem possible since java script
//doesn't recognize the "class" properties until the
//object is instantiated
function game(sizeX, sizeY, gridName){
this.gameGrid = new grid(3, 3, "Test Grid");
this.gridName = "Grid - " + this.gameGrid.name;
};
game.prototype.isWinner = function () {
for(var i=0; i< this.gameGrid.cells.length;i++){
//set to false if necessary
}
return true;
};
return game;
}]);
我现在可以正确引用Grid的属性。
function MyCtrl($scope, grid, game) {
var aGame = new game(3, 3, "Test Grid");
$scope.myGridName = aGame.gameGrid.name;
$scope.myLength = aGame.gameGrid.cells.length;
$scope.myGameName = aGame.gridName;
$scope.myWinner = aGame.isWinner();
}
然而,我仍然希望能够通过网格&#34; class&#34;进入游戏工厂。但这不起作用,因为grid.cells未定义,直到网格被实例化。这可以在Java Script / Angular中克服吗?
function game(grid){
this.gridName = "Grid - " + grid.name;
};
game.prototype.isWinner = function () {
for(var i=0; i< grid.cells.length;i++)
//set to false if necessary
}
return true;
};