问题
Is it possible to passing a function to a component and call this function inside the component passing a parameter?
Example:
List of posts
<post-list posts="blog.posts"
loading="blog.loadingPosts"
get-post-url="blog.getPostUrl"
is-user-authenticate="blog.user">
</post-list>
getPostUrl is a function (inside the container controller):
const getPostUrl = (postId) => {
const protocol = $location.protocol();
const host = $location.host();
const port = $location.port();
return protocol + "://" + host + "" + (port !== 80 ? ":" + port : "") + "/blog/post/" + postId;
};
List of posts: component
const PostList = {
"bindings": {
"posts": "<",
"loading": "<",
"getPostUrl": "&", //Function getPostUrl
"isUserAuthenticate": "<"
},
"template": `<div>
<div class="col-md-9 text-center" data-ng-if="$ctrl.loading">
<i class="fa fa-spinner fa-spin fa-2x"></i>
</div>
<div class="col-md-9 posts" data-ng-if="!$ctrl.loading">
<div data-ng-repeat="post in $ctrl.posts">
<post creation-date="{{post.creationDate}}"
content="{{post.content}}"
post-url="{{$ctrl.getPostUrl(post.creationDate)}}"
is-user-authenticate="$ctrl.user">
</post>
</div>
</div>
</div>`,
"transclude": false
};
angular
.module("blog")
.component("postList", PostList);
In this line:
post-url="{{$ctrl.getPostUrl(post.creationDate)}}"
I want to call the function passing a parameter and this function is returning a string.
In post component (not PostList) the postUrl is a string attribute @
.
But... Is not working!
angular.js:13550 Error: [$interpolate:interr] Can't interpolate: {{$ctrl.getPostUrl(post.creationDate)}} TypeError: Cannot use 'in' operator to search for 'blog' in 1459329888892 Error Link
Is it possible to do it? And how?
Thank you so much!
回答1:
If you want to call the function from inside a component and have it return a value then you need two-way binding:
"bindings": {
"posts": "<",
"loading": "<",
"getPostUrl": "=", // <-- two-way binding
"isUserAuthenticate": "<"
},
However, this is probably not very good idea. Consider passing data to component rather than making component request data from outside. This will make much better isolated component.
回答2:
You can pass functions to components, but you must define the function arguments as object with the correct arguments names as its keys. example:
<post-list posts="blog.posts"
loading="blog.loadingPosts"
get-post-url="blog.getPostUrl(postId)"
is-user-authenticate="blog.user">
</post-list>
const PostList = {
"bindings": {
"posts": "<",
"loading": "<",
"getPostUrl": "&", //Function getPostUrl
"isUserAuthenticate": "<"
},
"template": `<post creation-date="{{post.creationDate}}"
content="{{post.content}}"
post-url="{{$ctrl.getPostUrl({postId:post.creationDate})}}">
</post>
回答3:
To return a value to the binding function you must pass it as a object literal.
self.selected({id: '42', firstname: 'Douglas', lastname: 'Adams'});
angular.module('webapp').component('myComponent', {
templateUrl: 'myComponent.html',
bindings: {
selected: '&'
},
controller: function () {
var self = this;
self.someEvent= function(){
self.selected({id: '42', firstname: 'Douglas', lastname: 'Adams'});
};
}
});
Afterwards you can access the object literal values by it's properties.
id, firstname, lastname.
You can also pass additional parameters to the function. (myVariable)
<div>
<span ng-init="myVariable='Universe'">
<my-component selected="myFunction(id, firstname, lastname, myVariable)"></my-component>
</div>
$scope.myFunction = function(id, firstname, lastname, myVariable){
console.log(id, firstname, lastname, myVariable);
}
回答4:
According to Todd Motto's Standards, it is not suggested to use '=' instead try using '&' that is passing a method from parent to child component and calling the method in the child will trigger back in the parent. Let's take an example.
Parent Component's template(HTML):
<child take-me-to-school="$ctrl.searchBikeKeyAndStart>
Child Component's controller:
public someFunction = () => {
this.takeMeToSchool();
}
Once the function is called from the child component's controller then the function mapped in the parent will get triggered.
Parent Component's controller(HTML):
public searchBikeKeyAndStart = () => {
.....
}
When you want to pass an argument to the same function
Parent Component's template(HTML):
<child take-me-to-school="$ctrl.searchBikeKeyAndStart(**key**)>
Child Component's controller:
public someFunction = () => {
this.takeMeToSchool({key: parameterValue});
}
Once the function is called from the child component's controller then the function mapped in the parent will get triggered.
Parent Component's controller(HTML):
public searchBikeKeyAndStart = (**key**) => {
console.log(**key**) //will print the param passed
}
来源:https://stackoverflow.com/questions/36884303/angular-1-5-component-passing-a-function