nic*_*ine 278 javascript angularjs
我有一个控制器负责与API通信以更新用户的属性,名称,电子邮件等.每个用户都有一个'id'
在查看个人资料页面时从服务器传递的用户.
我想将此值传递给AngularJS控制器,以便它知道当前用户的API入口点是什么.我试过传递价值ng-controller
.例如:
function UserCtrl(id, $scope, $filter) {
$scope.connection = $resource('api.com/user/' + id)
Run Code Online (Sandbox Code Playgroud)
并在HTML中
<body ng-controller="UserCtrl({% id %})">
Run Code Online (Sandbox Code Playgroud)
其中{% id %}
打印从服务器发送的id.但我得到错误.
在创建时将值传递给控制器的正确方法是什么?
小智 359
笔记:
这个答案很老了.这只是关于如何实现预期结果的概念证明.但是,根据下面的一些评论,它可能不是最佳解决方案.我没有任何文档支持或拒绝以下方法.有关此主题的进一步讨论,请参阅以下一些评论.
原答案:
我回答这个是你绝对可以使用ng-init
和一个简单的初始化函数.
HTML
<!DOCTYPE html>
<html ng-app="angularjs-starter">
<head lang="en">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl" ng-init="init('James Bond','007')">
<h1>I am {{name}} {{id}}</h1>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
JavaScript的
var app = angular.module('angularjs-starter', []);
app.controller('MainCtrl', function($scope) {
$scope.init = function(name, id)
{
//This function is sort of private constructor for controller
$scope.id = id;
$scope.name = name;
//Based on passed argument you can make a call to resource
//and initialize more objects
//$resource.getMeBond(007)
};
});
Run Code Online (Sandbox Code Playgroud)
Mic*_*ler 141
我已经很晚了,我不知道这是不是一个好主意,但你可以$attrs
在控制器函数中包含注入,允许使用元素上提供的"参数"来初始化控制器,例如
app.controller('modelController', function($scope, $attrs) {
if (!$attrs.model) throw new Error("No model for modelController");
// Initialize $scope using the value of the model attribute, e.g.,
$scope.url = "http://example.com/fetch?model="+$attrs.model;
})
<div ng-controller="modelController" model="foobar">
<a href="{{url}}">Click here</a>
</div>
Run Code Online (Sandbox Code Playgroud)
再一次,不知道这是不是一个好主意,但似乎有效,是另一种选择.
Jon*_*ark 39
这也有效.
使用Javascript:
var app = angular.module('angularApp', []);
app.controller('MainCtrl', function($scope, name, id) {
$scope.id = id;
$scope.name = name;
// and more init
});
Run Code Online (Sandbox Code Playgroud)
HTML:
<!DOCTYPE html>
<html ng-app="angularApp">
<head lang="en">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<script src="app.js"></script>
<script>
app.value("name", "James").value("id", "007");
</script>
</head>
<body ng-controller="MainCtrl">
<h1>I am {{name}} {{id}}</h1>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
Fra*_*ain 15
像@akonsu和Nigel Findlater建议,可以读取URL其中URL是index.html#/user/:id
用$routeParams.id
和使用它的控制器内.
你的应用:
var app = angular.module('myApp', [ 'ngResource' ]);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/:type/:id', {templateUrl: 'myView.html', controller: 'myCtrl'});
}]);
Run Code Online (Sandbox Code Playgroud)
资源服务
app.factory('MyElements', ['$resource', function($resource) {
return $resource('url/to/json/:type/:id', { type:'@type', id:'@id' });
}]);
Run Code Online (Sandbox Code Playgroud)
控制器
app.controller('MyCtrl', ['$scope', '$routeParams', 'MyElements', function($scope, $routeParams, MyElements) {
MyElements.get({'type': $routeParams.type, "id": $routeParams.id }, function(elm) {
$scope.elm = elm;
})
}]);
Run Code Online (Sandbox Code Playgroud)
然后,elm
可以在视图中访问,具体取决于id
.
Nuc*_*eon 14
视图不应该指定配置
在Angular中,模板不应该指示配置,这本身就是人们在想要从模板文件向控制器传递参数时所需要的.这变成了一个滑坡.如果配置设置在模板中是硬编码的(例如通过指令或控制器参数属性),则除了单次使用之外,您不能再将该模板重新用于任何其他模板.很快你就会想要重复使用那个模板,但是使用不同的配置,现在为了做到这一点,你要么预处理模板,要么在传递给angular之前注入变量,要么使用大量的指令来吐出巨人HTML块,所以你可以重用所有的控制器HTML,除了包装div和它的参数.对于小型项目来说,这没什么大不了的.对于大的东西(角度擅长),它会变得很难看.
替代方案:模块
这种配置是模块设计用来处理的.在许多角度教程中,人们对整个应用程序都有一个模块,但实际上系统是设计完全支持许多小模块,每个模块都包含整个应用程序的一小部分.理想情况下,控制器,模块等将在单独的文件中声明,并在特定的可重用块中拼接在一起.当您的应用程序以这种方式设计时,除了简单的控制器参数之外,您还可以重复使用.
下面的示例有2个模块,重新使用相同的控制器,但每个模块都有自己的配置设置.该配置设置通过依赖注入使用传入module.value
.这符合角度方式,因为我们有以下内容:构造函数依赖注入,可重用控制器代码,可重用控制器模板(控制器div可以很容易地包含在ng-include中),易于单元测试的系统,没有HTML,最后可重复使用模块作为拼接在一起的车辆.
这是一个例子:
<!-- index.html -->
<div id="module1">
<div ng-controller="MyCtrl">
<div>{{foo}}</div>
</div>
</div>
<div id="module2">
<div ng-controller="MyCtrl">
<div>{{foo}}</div>
</div>
</div>
<script>
// part of this template, or a JS file designed to be used with this template
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById("module1"), ["module1"]);
angular.bootstrap(document.getElementById("module2"), ["module2"]);
});
</script>
<!-- scripts which will likely in be in their seperate files -->
<script>
// MyCtrl.js
var MyCtrl = function($scope, foo) {
$scope.foo = foo;
}
MyCtrl.$inject = ["$scope", "foo"];
// Module1.js
var module1 = angular.module('module1', []);
module1.value("foo", "fooValue1");
module1.controller("MyCtrl", MyCtrl);
// Module2.js file
var module2 = angular.module('module2', []);
module2.value("foo", "fooValue2");
module2.controller("MyCtrl", MyCtrl);
</script>
Run Code Online (Sandbox Code Playgroud)
看到它的实际效果:jsFiddle.
如果ng-init
不是为了传递对象$scope
,你总是可以编写自己的指令.所以这就是我得到的:
http://jsfiddle.net/goliney/89bLj/
Javasript:
var app = angular.module('myApp', []);
app.directive('initData', function($parse) {
return function(scope, element, attrs) {
//modify scope
var model = $parse(attrs.initData);
model(scope);
};
});
function Ctrl1($scope) {
//should be defined
$scope.inputdata = {foo:"east", bar:"west"};
}
Run Code Online (Sandbox Code Playgroud)
HTML:
<div ng-controller="Ctrl1">
<div init-data="inputdata.foo=123; inputdata.bar=321"></div>
</div>
Run Code Online (Sandbox Code Playgroud)
但我的方法只能修改已在控制器中定义的对象.
看起来最适合您的解决方案实际上是一个指令.这允许您仍然拥有控制器,但为其定义自定义属性.
如果需要访问包装范围中的变量,请使用此选项:
angular.module('myModule').directive('user', function ($filter) {
return {
link: function (scope, element, attrs) {
$scope.connection = $resource('api.com/user/' + attrs.userId);
}
};
});
<user user-id="{% id %}"></user>
Run Code Online (Sandbox Code Playgroud)
如果您不需要访问包装范围中的变量,请使用此选项:
angular.module('myModule').directive('user', function ($filter) {
return {
scope: {
userId: '@'
},
link: function (scope, element, attrs) {
$scope.connection = $resource('api.com/user/' + scope.userId);
}
};
});
<user user-id="{% id %}"></user>
Run Code Online (Sandbox Code Playgroud)
我发现来自$ routeProvider的传递变量很有用.
例如,您将一个控制器MyController用于多个屏幕,并在其中传递一些非常重要的变量"mySuperConstant".
使用这个简单的结构:
Router:
$routeProvider
.when('/this-page', {
templateUrl: 'common.html',
controller: MyController,
mySuperConstant: "123"
})
.when('/that-page', {
templateUrl: 'common.html',
controller: MyController,
mySuperConstant: "456"
})
.when('/another-page', {
templateUrl: 'common.html',
controller: MyController,
mySuperConstant: "789"
})
MyController:
MyController: function ($scope, $route) {
var mySuperConstant: $route.current.mySuperConstant;
alert(mySuperConstant);
}
Run Code Online (Sandbox Code Playgroud)
您可以在设置例如路线时执行此操作
.when('/newitem/:itemType', {
templateUrl: 'scripts/components/items/newEditItem.html',
controller: 'NewEditItemController as vm',
resolve: {
isEditMode: function () {
return true;
}
},
})
Run Code Online (Sandbox Code Playgroud)
后来用它作为
(function () {
'use strict';
angular
.module('myApp')
.controller('NewEditItemController', NewEditItemController);
NewEditItemController.$inject = ['$http','isEditMode',$routeParams,];
function NewEditItemController($http, isEditMode, $routeParams) {
/* jshint validthis:true */
var vm = this;
vm.isEditMode = isEditMode;
vm.itemType = $routeParams.itemType;
}
})();
Run Code Online (Sandbox Code Playgroud)
所以这里当我们设置我们发送的路由时:itemType并稍后从$ routeParams中检索它.
归档时间: |
|
查看次数: |
322011 次 |
最近记录: |