Projecting ngFor template in <ng-content> isn't working - javascript

I'm working on an Angular 4 project and I'm stuck on a problem regarding templates.
Let me explain it better.
I have two components in my project:
SectionCompontent.ts
HomeCompontent.ts
These are the relative HTML templates
section.compontent.html
<div class="section">
<div class="cards">
<ng-content></ng-content>
</div>
</div>
home.compontent.html
<section>
<div *ngFor="let card of cards">
<span>{{card.title}}</span>
</div>
</section>
When I run this project, I expect to see the rendered content of *ngFor projected inside SectionComponent where <ng-content> is located.
Unfortunately, this is what I see on the DOM instead of <ng-content>:
<!--bindings={}-->
I added some static HTML tags like <p> and <h1> and they allowed it to work.
Can you help me solve this problem?
Thanks in advance.

Related

Add Component or Directive to HTML template received from the server

Let's say an endpoint returns this HTML:
<div data-type="section">
<div data-type="section-header">
Section 1
</div>
<div data-type="section-body">
Lorem ipsum
</div>
</div>
Above template will be stored in component property sections. In an Angular app we will append this HTML to the page via <div class="sections-container" [innerHtml]="sections"></div>.
Before appending HTML template to innerHtml, is it possible to add component or directive to the HTML template received from the backend?
For example we have HighlightDirective, which will set background to yellow and we want to apply it to data-type="section-header" element, so that HTML template will look like this:
<div data-type="section">
<div data-type="section-header" appHighlight>
Section 1
</div>
<div data-type="section-body">
Lorem ipsum
</div>
</div>
Will Angular automatically recognize the appHighlight directive and add it to the component tree? Or it's necessary to hydrate this HTML template?
The solution that I have found it is wrapped HTML into anonymous component and handle string from BE. Then compile that and looks like everything is ok.
Stackblitz example

How to create a custom refinement list in vue instant search?

I am working with Laravel Scout and alogolia as the driver. Since I have vue on the front end, I tried the vue instant search package which works really well.
The issue that I am facing is that I need to customize it to the in app styles we are using.
Refinement Section
This is the particular component I am trying to customize. It tried over riding the classes like they show in Styling Section but that won't cut it for me since I need to add more tags and attributes in there.
<ais-refinement-list attribute-name="categories.title" inline-template>
<div class="column w-1/5">
Hello
</div>
</ais-refinement-list>
Now I know I can start to write an inline template like so but what I don't understand yet, is how to get the values for refinements so I can make the checkboxes and furthermore how to send them back to the component once they are selected. Any help is appreciated.
I dug through the package it self here and then found the template inside here. For some reason I could not see this in vendor code.
Got all the variables and method calls from in there
This is the custom version:
<ais-refinement-list attribute-name="categories.title" inline-template>
<div class="column w-1/5">
<h3>Categories</h3>
<hr class="my-3">
<div class='column w-full mb-4' v-for="facet in facetValues">
<div class="checkbox-control mb-4">
<input type="checkbox" :id="facet.name" :value="facet.name" v-model="facet.isRefined" #change="toggleRefinement(facet)"/>
<label :for="facet.name">{{ facet.name }} ({{ facet.count }})</label>
</div>
</div>
</div>
</ais-refinement-list>

Nest/Share Angular applications

I have 2 list of items say, news and people.
These 2 lists have different logic and are located in different pages, so don't share shame ng-app:
<!-- News.html -->
<div id="newsList" ng-app="newsListApp">
<div id="{{news.id}}" ng-app="modalApp" ng-repeat="news in newsList">
...
</div>
</div>
<!-- People.html -->
<div id="peopleList" ng-app="peopleListApp">
<div id="{{person.id}}" ng-app="modalApp" ng-repeat="person in people">
...
</div>
</div>
I need to open each item in a modal popup, so I have to use a modalApp, but I want to use the same modalApp(that will use the same popup template) in the news and people lists...
What is the concept of sharing angular application/modules in cases like this?
You can't do it using ng-app. You have to manually bootstrap at least one of them. See this question for more info.
I think you are mixing up ng-app and ng-controller. Probably you are looking for something like this. In general angular only expects one app per page, and they certainly shouldn't be nested
<body ng-app="myApp">
<div id="newsList" ng-controller="newsListCtrl">
<div id="{{news.id}}" ng-controller="modalCtrl" ng-repeat="news in newsList">
...
</div>
</div>
<div id="peopleList" ng-controller="peopleListCtrl">
<div id="{{person.id}}" ng-controller="modalCtrl" ng-repeat="person in people">
...
</div>
</div>
</body>
https://docs.angularjs.org/api/ng/directive/ngController
Edit:
If news and people are different pages then you need a router of some kind. Your main options are ngRoute or ui-router. I think ui-router is more flexible to I would go with that. Couple of useful links that might help out:
https://scotch.io/tutorials/angular-routing-using-ui-router
http://plnkr.co/edit/dd8Nk9PDFotCQu4yrnDg?p=preview

Nested vue.js instances/elements

This may sound like a real noob question, but I'm pretty new to MVVM... or even MVC in JS, so sorry in advance.
I'm playing about with vue.js, and loving the simplicity of it so far. But for what I am trying to do, I think I need to go about it a different way.
I want to nest Vue instances/elements inside each other, but of course, the parent will then use the child when it reads through the DOM on init.
For the sake of arguments, below is an example of what I mean, I am not doing anything like this, but this is the simplest way to example what I mean:
<body>
{{ message }}
<div id="another">
{{ message }}
</div>
</body>
Then my JS for example would be:
new Vue({
el: "body",
data: {
message: "I'm the parent"
}
});
new Vue({
el: "#another",
data: {
message: "I'm the child"
}
});
The outcome would be:
<body>
I'm the parent
<div id="another">
I'm the parent
</div>
</body>
Now I completely understand why it is doing this and in fact, it should do this, but my example is just trying to illustrate how I would do something like this?
In my real life project, I have a v-class on my body that changes when stuff happens in the body (in numerous places) but of course my body will also want other instances of vue that do other stuff.
how would I go about nesting? Is there feature in vue to deal with this? Do I need to deal with components? Or maybe, fetch the body from within a child element (e.g. like jQuery would with $("body")) then manipulate it within the Vue instance?
Hope this question isn't too stupid and someone can point me in the right direction.
Thanks
Think components.
http://vuejs.org/guide/components.html
Create a Vue instance on the body as you have above, but anything nested in that is a component. Pass data via props.
Passing in data via props is only one way to do it. Nesting components and inheriting from the parent works fine as well.
Example: http://jsfiddle.net/hajkrupo/3/
<encapsulated-component inline-template>
<header>
<cart-status></cart-status>
</header>
<cart></cart>
</encapsulated-component>
You can do this with <slot> tags. Here is an example.
1.So, first, you need to do is creating a basic layout component, like this.
You need to add <slot> tag whereever you want. Very important think is the name attribute on <slot> tag.
var basicLayout = Vue.component("basic-layout", {
template: `
<div class="basic-layout">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
`
});
2.Then create your custom component. I created myHeader component to show you, how it works.
var myHeader = Vue.component("my-header", {
template: `
<div class="header">
<ul>
<li>HOME</li>
<li>ABOUT</li>
<li>CONTACT</li>
</ul>
</div>
`
});
3.Put this sample code in your HTML file.
To put some content in current slot, just use the slot attribute in your component or your tag.
<div class="app">
<basic-layout>
<my-header slot="header"></my-header>
<p>Content in <main> tag</p>
<p slot="footer">Content in footer</p>
</basic-layout>
</div>
4.The result will be like this:
<div class="app">
<div class="basic-layout">
<header>
<div class="header">
<ul>
<li>HOME</li>
<li>ABOUT</li>
<li>CONTACT</li>
</ul>
</div>
</header>
<main>
<p>Content in <main> tag</p>
<main>
<footer>
<p>Content in footer</p>
</footer>
</div>
</div>
Please, see the documentation in official page of Vue.js
Just click link here for more info.
Here is example in jsfiddle

ng-include dont work on ng-show

I have a simple angular app but the template is growing. I want to split it and use the ng-include directive but I can't get it to include correctly.
current template.html
<div class="edit-object-form" ng-show="editable">
<!-- ... -->
</div>
<div class="list-objects" ng-show="!editable">
<!-- ... -->
</div
desired template.html
<div class="edit-object-form" ng-show="editable">
<div ng-include="/partials/edit_objet_form.html"></div
</div>
<div class="list-objects" ng-show="!editable">
<!-- ... -->
</div
The default value of editable is false, but when I switch to true the include directive doesn't work.
Note: I'm using Angular-1.0.7
I'm not able to recreate this issue. Take a look at this plunker that loads two different templates. (The both look odd, since they're templates stolen from other plunkers to allow for xss).
Maybe this issue is caused by the two incomplete div ending tags, that are .

Categories

Resources