问题
I'm trying to dynamically generate form inputs and an associated action menu based on the model. I'm able to pass the field to be used and the menu, but I can't figure out how to configure ng-click to call the appropriate function defined in the model. See fiddle : http://jsfiddle.net/ahonaker/nkuDW/
HTML:
var myApp = angular.module('myApp',[]);
myApp.directive('myDirective', function($compile) {
return {
restrict: "E",
replace: true,
scope : {
field: '=',
label: '=',
menu: '='
},
link: function (scope, element, attrs) {
element.html('{{label}}: <input ng-model="field"> <ul ng-repeat="item in menu"<li><a ng-click="item.func">{{item.title}}</a></li></ul>');
$compile(element.contents())(scope);
}
}
});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.status = 'You have not picked yet';
$scope.menu = [
{ "title" : "Action 1", "func" : "ActionOne()"},
{ "title" : "Action 2", "func" : "ActionTwo()"},
]
$scope.fieldOne = "I am field 1";
$scope.fieldTwo = "I am field 2";
$scope.ActionOne = function() {
$sopce.status = "You picked Action 1";
}
$scope.ActionOne = function() {
$sopce.status = "You picked Action 2";
}
}
JS:
<div ng-app = "myApp">
<div ng-controller="MyCtrl">
<ul>
<p><my-directive field="fieldOne" label="'Field 1'" menu="menu"></my-directive></p>
<p><my-directive field="fieldTwo" label="'Field 2'" menu="menu"></my-directive></p>
</ul>
Hello, {{status}}!
</div>
</div>
Any help would be appreciated. I've tried the following ng-click approaches in the directive
ng-click={{item.func}}
ng-click="item.func"
ng-click="{{item.func}}"
What am I doing wrong? Or is there a better way to do this (the menu structure including the functions to be called have to come from the model in order for me to build a generic form generation capability).
回答1:
Here's your fixed fiddle: http://jsfiddle.net/nkuDW/1/
There were a great number of problems with it.
- You've got a typo
$scopetypo'd 4 times as$sopce. - If you want items within
$scope.menuto have access toActionOneandActionTwo, you'll need to define those Action functions above where you define$scope.menu(that's just how JavaScript works when you're assigning functions to variables). - You've got
ActionOnedefined twice, where the second one should beActionTwo. - ng-click is expecting a method call, not a pointer to a function so it should be
ng-click="item.func()". - You want your menu items to have pointers to functions, but you've defined them as strings... even if you take
"ActionOne()"out of quotations, it still won't work for two reasons:ActionOnedoesn't exist as a funcion inside of MyCtrl, instead it needs to be referenced as$scope.ActionOne- You just want a pointer to ActionOne, you don't actually want to call it at this point. Because of the parenthesis, both actions would be called when MyCtrl is initalized.
It would probably be a good idea to understand the basics of JavaScript before jumping into Angular, as Angular assumes you have a good understanding of the nuances of the language. There are a series of videos by Douglas Crockford that can get you started.
回答2:
I didn't want to deal with having html code in my angular app, or directives, or the use of eval. so I just wrapped my existing functions in a function:
$scope.get_results = function(){
return {
message: "A message",
choice1: {message:"choice 1 message", f: function(){$scope.alreadyDefinedFunction1()}},
choice2: {message:"choice 2 message", f: function(){$scope.alreadyDefinedFunction2()}},
};
}
in a different function:
$scope.results2 = $scope.get_results();
Snippet of use in html:
<ul class="dropdown-menu scroll-div">
<li><a ng-click="results2.choice1.f()">{{results_2_menu.choice1.message}}</a></li>
<li><a ng-click="results2.choice2.f()">{{results_2_menu.choice2.message}}</a></li>
</ul>
Was based on this js fiddle: http://jsfiddle.net/cdaringe/FNky4/1/
来源:https://stackoverflow.com/questions/16112445/how-do-i-dynamically-define-a-function-to-call-with-ng-click-in-angularjs-direct