假设您有一个从数据库加载值的表单。你如何初始化ng-model?
示例:
<input name="card[description]" ng-model="card.description" value="Visa-4242">
在我的控制器中,$ scope.card最初是未定义的。除了做这样的事情之外还有办法吗?
$scope.card = {
description: $('myinput').val()
}
答案 0 :(得分:236)
如果您无法修改您的应用以执行@blesh建议的操作(使用$ http或$ resource拉下JSON数据并填充$ scope),则可以使用ng-init代替:
<input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">
另见AngularJS - Value attribute on an input text box is ignored when there is a ng-model used?
答案 1 :(得分:135)
这是新Angular应用程序中的常见错误。如果可以避免,则不希望将值写入服务器上的HTML。事实上,如果你可以让你的服务器完全呈现HTML,那就更好了。
理想情况下,您希望发送Angular HTML模板,然后通过JSON中的$ http下拉您的值并将它们放在您的范围内。
因此,如果可能,请执行此操作:
app.controller('MyController', function($scope, $http) {
$http.get('/getCardInfo.php', function(data) {
$scope.card = data;
});
});
<input type="text" ng-model="card.description" />
如果绝对必须从服务器将值呈现到HTML中,可以将它们放在全局变量中并使用$ window访问它们:
在你的页面标题中你写出:
<head>
<script>
window.card = { description: 'foo' };
</script>
</head>
然后在你的控制器中你会得到它:
app.controller('MyController', function($scope, $window) {
$scope.card = $window.card;
});
我希望有所帮助。
答案 2 :(得分:60)
这是一个显然缺乏但很容易添加的AngularJS修复程序。只需编写一个快速指令,即可从输入字段设置模型值。
<input name="card[description]" value="Visa-4242" ng-model="card.description" ng-initial>
这是我的版本:
var app = angular.module('forms', []);
app.directive('ngInitial', function() {
return {
restrict: 'A',
controller: [
'$scope', '$element', '$attrs', '$parse', function($scope, $element, $attrs, $parse) {
var getter, setter, val;
val = $attrs.ngInitial || $attrs.value;
getter = $parse($attrs.ngModel);
setter = getter.assign;
setter($scope, val);
}
]
};
});
答案 3 :(得分:12)
恕我直言,最好的解决方案是@Kevin Stone指令,但我必须升级它才能在各种条件下工作(f.e.select,textarea),而这一点肯定是有效的:
angular.module('app').directive('ngInitial', function($parse) {
return {
restrict: "A",
compile: function($element, $attrs) {
var initialValue = $attrs.value || $element.val();
return {
pre: function($scope, $element, $attrs) {
$parse($attrs.ngModel).assign($scope, initialValue);
}
}
}
}
});
答案 4 :(得分:7)
您可以使用自定义指令(支持textarea,选择,广播和复选框),请查看此博文https://glaucocustodio.github.io/2014/10/20/init-ng-model-from-form-fields-attributes/。
答案 5 :(得分:6)
您也可以在HTML代码中使用:
ng-init="card.description = 12345"
Angular不推荐使用,如上所述,您应该只使用您的控制器。
但它有效:)
答案 6 :(得分:4)
我有一个简单的方法,因为我的表格中有一些重要的验证和掩码。因此,我使用jquery再次获得我的价值并开启事件&#34;更改&#34;验证:
class SocketHandler(WebSocketHandler):
def on_message(self, message):
ball = json.loads(message)
user = User(ball['identifier'])
if ball['command'] == 'search':
global our_mongo
search_results = our_mongo.find({'$text':{'$search':ball['search_term']}},{'score':{'$meta':"textScore"}})
self.write_message({
'command': 'search-results',
'results': list(search_results.sort([('score', {'$meta': 'textScore'})]).limit(10)),
})
elif ball['command'] == 'save-node': # hopefully this can handle both new nodes and changes to nodes
node_dict = ball['node_dict']
if 'importance' in node_dict.keys():
node_dict['importance'] = int(node_dict['importance'])
try:
node_obj = node.create_appropriate_node(node_dict)
print('node made. looks like: '+str(node_obj)+'. Now time to put it into the DB...')
global our_mongo
# take a look at the dependencies now
previous_dependency_ids = [node.reduce_string(dependency) for dependency in list(our_mongo.find({"_id": node_obj.id}))[0]["_dependencies"]] # if this works, try using set() instead of list and elimination the set()s below
print('prev deps are: '+str(previous_dependency_ids))
our_mongo.upsert({ "_id": node_obj.id }, node_obj.__dict__)
# take a look at the current dependencies
current_dependency_ids = [node.reduce_string(dependency) for dependency in list(our_mongo.find({"_id": node_obj.id}))[0]["_dependencies"]] # if this works, try using set() instead of list and elimination the set()s below
print('curr deps are: '+str(current_dependency_ids))
update_our_DAG()
# send an update of the graph to the user if there is a new dependency:
for new_dependency in set(current_dependency_ids) - set(previous_dependency_ids):
self.request_node(new_dependency, ball, user)
# OR IF THE SAVED NODE IS A BRAND NEW NODE, we have to include all the deps
except Exception as error:
# stuff didn't work, send error back to user
print('ERROR: '+str(error))
self.write_message({
'command': 'display-error',
'message': str(error),
})
def update_our_DAG():
# 1. grab nodes and edges from database
all_node_dicts = list(Mongo("math", "nodes").find())
# 2. create a networkx graph with the info...
global our_DAG
our_DAG = nx.DAG()
for node_dict in all_node_dicts:
node = create_appropriate_node(strip_underscores(node_dict))
our_DAG.add_n(node)
def make_app():
return Application(
[
url('/', RedirectHandler, {"url": "index.html"}, name="rooth"),
url('/websocket', SocketHandler),
url('/json', JSONHandler, name="jsonh"),
url(r'/index(?:\.html)?', IndexHandler, name="indexh"),
# captures anything at all, and serves it as a static file. simple!
url(r'/(.*)', StaticHandler, {"path": "../www/"}),
],
# settings:
debug=True,
)
def make_app_and_start_listening():
# enable_pretty_logging()
application = make_app()
# by listening on the http port (default for all browsers that i know of),
# user will not have to type "http://" or ":80" in the URL
application.listen(80)
# other stuff
IOLoop.current().start()
if __name__ == "__main__":
# 0. create a global mongo object for later use (for upserts in the future)
our_mongo = Mongo("math", "nodes")
# 1 and 2
update_our_DAG()
axioms = [our_DAG.n(node_id) for node_id in ['set', 'multiset', 'vertex']]
# 3. launch!
make_app_and_start_listening()
答案 7 :(得分:3)
正如其他人所指出的,初始化视图数据并不是一种好习惯。 但是,建议在控制器上初始化数据。 (见http://docs.angularjs.org/guide/controller)
所以你可以写
<input name="card[description]" ng-model="card.description">
和
$scope.card = { description: 'Visa-4242' };
$http.get('/getCardInfo.php', function(data) {
$scope.card = data;
});
这样,视图不包含数据,并且控制器在加载实际值时初始化值。
答案 8 :(得分:3)
如果你喜欢Kevin Stone的方法https://stackoverflow.com/a/17823590/584761 通过为特定标签(例如“输入”)编写指令,可以考虑更简单的方法。
app.directive('input', function ($parse) {
return {
restrict: 'E',
require: '?ngModel',
link: function (scope, element, attrs) {
if (attrs.ngModel) {
val = attrs.value || element.text();
$parse(attrs.ngModel).assign(scope, val);
}
}
}; });
如果你走这条路线,你不必担心在每个标签上添加ng-initial。它会自动将模型的值设置为标记的value属性。如果未设置value属性,则默认为空字符串。
答案 9 :(得分:3)
这是一种以服务器为中心的方法:
<html ng-app="project">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script>
// Create your module
var dependencies = [];
var app = angular.module('project', dependencies);
// Create a 'defaults' service
app.value("defaults", /* your server-side JSON here */);
// Create a controller that uses the service
app.controller('PageController', function(defaults, $scope) {
// Populate your model with the service
$scope.card = defaults;
});
</script>
<body>
<div ng-controller="PageController">
<!-- Bind with the standard ng-model approach -->
<input type="text" ng-model="card.description">
</div>
</body>
</html>
除了$provide.value注册包含默认值的服务外,它与此问题上比较流行的答案具有相同的基本思想。
因此,在服务器上,你可以有类似的东西:
{
description: "Visa-4242"
}
通过您选择的服务器端技术将其放入您的页面。这是一个要点:https://gist.github.com/exclsr/c8c391d16319b2d31a43
答案 10 :(得分:1)
这是上面提到的想法的更通用的版本...... 它只是检查模型中是否有任何值,如果没有,则将值设置为模型。
JS:
<select class="form-control"
ng-options="v for (i, v) in compressionMethods"
ng-model="action.parameters.Method"
default-value="'LZMA2'"></select>
HTML(用法示例):
{
"System": "2334",
"Id": "AP64531346-2016055553824",
"dtis": "106165099",
"Type": "Up",
... (in total, 112 lines per record)
}
{
"System": "873",
"Id": "AP24531346-20160676553824",
"dtis": "1261699",
"Type": "Up",
... (in total, 112 lines per record)
}
答案 11 :(得分:0)
我尝试了@Mark Rajcok的建议。它适用于String值(Visa-4242)。 请参阅此fiddle。
来自小提琴:
在小提琴中完成的同样的事情可以使用ng-repeat
来完成,每个人都可以推荐。但在阅读了@Mark Rajcok给出的答案之后,我只是想对包含一系列配置文件的表单进行相同的尝试。
事情很顺利,直到我有$ scope.profiles = [{},{}];控制器中的代码。如果我删除此代码,我得到错误。
但在正常情况下,当我从服务器打印或回显html时,我无法打印$scope.profiles = [{},{}];
。
是否可以像@Mark Rajcok那样对<input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">
这样的字符串值执行上述操作,而不必从服务器回显JavaScript部分。
答案 12 :(得分:0)
刚刚为Ryan Montgomery添加了对select元素的支持“fix”
<select class="input-control" ng-model="regCompModel.numberOfEmployeeId" ng-initial>
<option value="1af38656-a752-4a98-a827-004a0767a52d"> More than 500</option>
<option value="233a2783-db42-4fdb-b191-0f97d2d9fd43"> Between 250 and 500</option>
<option value="2bab0669-550c-4555-ae9f-1fdafdb872e5"> Between 100 and 250</option>
<option value="d471e43b-196c-46e0-9b32-21e24e5469b4"> Between 50 and 100</option>
<option value="ccdad63f-69be-449f-8b2c-25f844dd19c1"> Between 20 and 50</option>
<option value="e00637a2-e3e8-4883-9e11-94e58af6e4b7" selected> Less then 20</option>
</select>
app.directive('ngInitial', function () {
return {
restrict: 'A',
controller: ['$scope', '$element', '$attrs', '$parse', function ($scope, $element, $attrs, $parse) {
val = $attrs.sbInitial || $attrs.value || $element.val() || $element.text()
getter = $parse($attrs.ngModel)
setter = getter.assign
setter($scope, val)
}]
}
});
答案 13 :(得分:0)
如果在mypage/id
这样的URL中有init值,那么在angular JS的控制器中,您可以使用location.pathname
来查找id并将其分配给您想要的模型。