问题
Currently I'm trying to render a specific data on angular with node/express as the backend.
What I'm trying to achieve is whenever a user clicks a specific story, it will link to that specific story page that belongs to a user who created the story.
api.js
apiRouter.get('/:user_name/:story_id', function(req, res) {
User.findOne({ name: req.params.user_name }, function(err, user, next) {
if(err) return next(err);
Story.findById(req.params.story_id, function(err, story) {
if(err) {
res.send(err);
return;
}
res.json({
name: user.name,
story_id: story._id,
content: story.content
});
});
});
});
As for the backend(api) It does show the specific data that I wanted with POSTMAN chrome tool but when it comes to angular I'm really confuse of how to render the data to the html.
service.js
storyFactory.getSingleStory = function(user_name, story_id) {
return $http.get('/api/' + user_name + story_id);
}
controller.js
angular.module('storyCtrl', ['storyService'])
.controller('StoryController', function(Story, $routeParams) {
var vm = this;
Story.getSingleStory($routeParams.user_name, $routeParams.story_id)
.success(function(data) {
vm.storyData = data;
});
});
app.routes.js
.when('/:user_name/:story_id', {
templateUrl: 'app/views/pages/users/single.html',
controller: 'StoryController',
controllerAs: 'story'
})
index.html ( Just going to show the line where it goes to the single.html )
<a href="/{{ main.user.name }}/{{ each._id }}"><h4>{{ each.content }}</h4>
single.html
Hello {{ main.user.name }}
<p>{{ story.content }}</p>
So far I couldn't manage to render the data properly with angular while with node/express I could query the data that I wanted with POSTMAN. I'm clueless and please save me from this confusion that angular giving me :)
回答1:
I have went through your code, and you can improve in following parts:
Instead of using
var vm = this
in your controller, you should bind all objects to$scope
, which is the key to two-way data binding. For instanceangular.module('storyCtrl', ['storyService']) .controller('StoryController', function($scope, Story, $routeParams) { var vm = this; Story.all().success(function(data) { $scope.stories = data; });
Then
stories
can be accessed in View directly. It would be more readable thancontrollerName.stories
in HTML.<div class="col-md-6" ng-controller="StoryController as story"> <div class="panel-body" ng-repeat="story in stories"> <div class="comment-text"> <a href="/{{ main.user.name }}/{{ story._id }}"><h4>{{ story.content }}</h4></a> </div> </div> </div>
Keep in mind,
then(function(response))
will only pass one parameter to the chained function while.success(function(data, status, headers, config))
will retrieve data from HTTP response. Then your code to load single story can be converted toStory.getSingleStory($routeParams.user_name, $routeParams.story_id) .then(function(data, status, headers, config) { $scope.storyData = data; });
Now we can access
storyData
in View.There is a tiny bug in your Story Service. Change
generateReq('GET', '/api/' + user_name + story_id)
togenerateReq('GET', '/api/' + user_name + '/' + story_id)
回答2:
If you want to set values on the controller and see them in the html view. Set the view model on the controller's scope rather than using this. This and scope are not always the same thing and for binding I believe you need scope.
回答3:
these expressions
// file: single.html
{{ main.user.name }}
<p>{{ story.content }}</p>
don't seem to be bound to any variable in 'StoryController'
Try using
// file: single.html
{{ story.storyData.user.name }}
<p>{{ story.storyData.content }}</p>
回答4:
Your problem may be due to the fact that you story data is html
and is therefore untrusted by default. For security reasons Angular will not allow you to render html directly into the page, instead you must explicitly tell Angular to trust the html content
To do this you must first include the ngSanitize module in your app.
angular.module('app', ['ngSanitize']);
You can then inject the $sce service which allows you to trust the html content. The code below has a data item
with a property called Html
that contains raw html text returned from an api. I just overwrite this raw html text with the $sce trust object returned from the $sce.trustAsHtml()
method.
item.Html = $sce.trustAsHtml(item.Html);
Once you have trusted your html, you are now free to render it using the ng-bind-html
attribute.
<div ng-bind-html="item.Html"></div>
For more information and further examples see:
- Insert HTML into view using AngularJS
- ngBindHtml
来源:https://stackoverflow.com/questions/28264255/having-trouble-on-rendering-data-to-angular