问题描述:

This may be very simple but I can't find the appropriate documentation to explain how to overcome my issues, here goes: I have a repeater that is like so...

 <tr ng-repeat="thing in things">

<td>{{ thing.name }}</td>

<td>{{ thing.category }}</td>

<td>{{ thing.content }}</td>

<td>{{ thing.confirms }}</td>

<td>{{ thing.declines }}</td>

<td> <button ng-click="doSomething('{{ thing }}')">Do what we want</button></td>

</tr>

Now all works well and expected. In the doSomething function that is in a service I have written I wish to pass a 'thing' object as an argument that I have cast to a string to avoid errors (I'll convert it later). Now when I output that object to my service the object contents are not returned (although they are displayed in the rendered HTML). What is passed to my service is the string "{{ thing }}" not the object values (so my JSON.parse fails) this the rendered HTML from the Chrome Dev Tool:

doSomething('{"name":"Debbie Harry","id":"526f9eb7e4b0b5062e14c1dc","category":"Basic Info","content":"Debbie Harry is cool","confirms":5,"declines":0}')

How would I overcome this? How to I make sure that the JSON object is passed and not the AngularJS curly braces declaration?

If I am not explaining myself well please state so and I shall re-word my issue.

网友答案:

Do it like this

<td> <button ng-click="doSomething(thing)">Do what we want</button></td>

Or you may can do (but don't do this)

<td> <button ng-click="doSomething(" + {{thing}} + ")">Do what we want</button></td>

The ngClick directive reads the value and parse it as JavaScript, so you can use the thing variable as is. The thing variable is accessible inside the ng-repeat block.

If you dig into the angularjs source, you can find this code. This will help you to understand how the ngClick directive works.

var ngEventDirectives = {};
forEach(
'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress'.split(' '),
function(name) {
  var directiveName = directiveNormalize('ng-' + name);
  ngEventDirectives[directiveName] = ['$parse', function($parse) {
    return function(scope, element, attr) {
      var fn = $parse(attr[directiveName]);
      element.bind(lowercase(name), function(event) {
        scope.$apply(function() {
          fn(scope, {$event:event});
        });
      });
    };
  }];
}
);
网友答案:

While Sangdol provided correct answer I would like to explain a bit what's happening behind the scenes.

ngClick directive internally uses $parse service to evaluate expression doSomething('{{ thing }}') and invokes it on current $scope. So basically angular is looking for doSomething function in current (or parent) scope and then executes it with argument '{{ thing }}', which is a string. You see, thing in this context is not the variable, it is a part of the string, as in any JS code. If you remove the quotes, $parse will look not only doSomething in the scope, but property thing as well. What I'm describing is angular expressions and they're basically a subset of javascript. For example, if you provide reference to alert in your scope ($scope.alert = window.alert), you can write something like

<button ng-click="alert(2+2)">button</button>

not only angular will invoke alert dialog, but also evaluate 2+2 to 4.

相关阅读:
Top