Multiple components scope conflict - angularjs

I am working on an admin panel application which is based on AngularJS 1.5. It is structured as follows:
There is a main component called app, in which I am using all other components.
app.html
<div class="wrapper">
<message-component></message-component>
<header></header>
<leftbar></leftbar>
<body></body>
</div>
In the body component, I am using ui-view to render my component based on the current route.
At one time, three components are usually present : header, leftbar and body. I am using ng-if directive in my leftbar component in which I am calling a function.
leftbar.html
<li ng-if="leftbar.hasPermission('FOO')">
<a ui-sref="foo">
<span>Demo Page</span>
</a>
</li>
leftbar.controller
class LeftbarController {
constructor() {}
hasPermission(name) {
return user[name];
}
}
It basically shows the <li> if the user has a permission named "FOO".
Now, simultaneously my body component is also visible to the user and there is an input field present inside that, so whenever I write something in that field hasPermission method also gets called which is present in a different component.
So what can be the issue here? Why scopes are behaving like this ?

Related

Rendering same React Component with different properties at different div id

I am trying to render single react component with different properties at different div id
index.html:
<div class="container" id="root1"></div>
<div class="container" id="root2"></div>
There are two hyperlinks and onClick will catch the id of the hyperlink, I have bound root1 and root2 to both the hyperlinks and calls the function(prop, containerID)
file.js:
function(prop, containerID){
ReactDOM.render(<component prop={prop}/>, document.getElemntById(containerID));
}
after this statements i can see only 'prop2' at both the divisions 'root1' and 'root2' and if i change the order of ReactDOM.render by 'root2' and then 'root1', then only 'prop1' is visible at both 'root1' and 'root2'.
But I need 'prop1' at 'root1' and 'prop2' at 'root2'.
Is there anything I need to add more to the above code or any other alternative way to implement this view?

child of angularjs component

How can a child DOM of an angularjs component access the component's variable values?
To illustrate, I am using angular official website first component example. I added a div inside the component.
<span>Name: {{$ctrl.hero.name}}</span>
<!--The following is the child of the component,
which is not showing component's variable as expected -->
<div ng-controller="InnerCtrl">
Inside the component, Name: {{$ctrl.hero.name}}
</div>
Here is the plunker

Where to place modals in a simple React application?

I am building a simple React application that implements CRUD operations on the client-side and communicates with a backend via Ajax. I have a container component that has a list component that has many items.
So I have a component with a form to create a new item. I can also write a similar form to edit an item in the list. But I wanted to actually make a modal popup instead of just having a form on the same view. Typically, for instance, with Materialize, you have the following:
<!-- Modal Trigger -->
<a class="waves-effect waves-light btn modal-trigger" href="#modal1">Modal</a>
<!-- Modal Structure -->
<div id="modal1" class="modal">
<div class="modal-content">
<h4>Modal Header</h4>
<p>A bunch of text</p>
</div>
<div class="modal-footer">
Agree
</div>
</div>
$(document).ready(function(){
// the "href" attribute of .modal-trigger must
// specify the modal ID that wants to be triggered
$('.modal-trigger').leanModal();
});
So I have an edit button in each list item that would actually be the first part of the code above. Now my question is: where should the second part of the code -- the modal itself -- go in the structure of my React components? If I place it in the ListItem component, then every item is going to have a modal. My idea was to place the modal structure in the container component, right after the List component itself. But it does not seem to be working. So where exactly would you place your modal structure if you are using React? Note: I am not using Flux nor Redux, I am just trying to build a simple application using state and props.
// ContainerComponent:
<List>
<NewItemForm>
// I put the modal code inside the EditForm component,
// but it doesn't seem to be trigger from the ListItem edit button :/
<EditForm>
// My ContainerComponent has the following code in componentDidMount:
$('.modal-trigger').leanModal();

Angular 1.5 Parent-Child Component Issue

I'm using Angular 1.5 Component router and having trouble getting a scope variable in the parent to be accessible in child components. I've created a plunker here that illustrates the problem. I've created a parent component with this view:
<nav>
<ul class="linkList">
<li><a ng-class="{selected: $ctrl.isSelected('Applications')}" ng-link="['Applications', {search:$ctrl.search}]">Applications</a></li>
<li><a ng-class="{selected: $ctrl.isSelected('Processes')}" ng-link="['Processes']">Processes</a></li>
<li><a ng-class="{selected: $ctrl.isSelected('Tasks')}" ng-link="['Tasks']">Tasks</a></li>
<li><a ng-class="{selected: $ctrl.isSelected('Resources')}" ng-link="['Resources']">Resources</a></li>
</ul>
<div class="filter">
Filter: <input type="search" ng-model="$ctrl.search" />
</div>
<div class="clear"></div>
</nav>
<ng-outlet></ng-outlet>
Notice the "search" variable in the parent component view. I want this to be accessible to child components, but it's not working for me. I've seen examples that show child components being directly referenced in parent components like the following:
<application-grid search="$ctrl.search"></application-grid>
However, doesn't this defeat the purpose of the ng-outlet? I don't think I should have to manually pass parameters to child components like this right? What is the right way to do this?
Just stumbled upon this - hoping you found the solution but if not here it is.
You can get this to work easily using the require property.
Just add this to you child component set up and bingo:
require: {
parent: '^app'
}
Then to access the parent scope object do $ctrl.parent.search.
Note you don't have to call it parent - it can be what ever name you like.
I've forked your plunkr - see it working http://plnkr.co/edit/epPg2xWY6IYJN2Fnvg61
You can access the route parameters through the $routerOnActivate lifecycle hook, which gets called automatically when the route transitions to that component. Here's the example from the Angular docs:
function HeroDetailComponent(heroService) {
var $ctrl = this;
this.$routerOnActivate = function(next, previous) {
// Get the hero identified by the route parameter
var id = next.params.id;
return heroService.getHero(id).then(function(hero) {
$ctrl.hero = hero;
});
};
...
Also, it's worth noting that components created with angular.module().component() always have isolate scopes - i.e., you can't access scope variables from the parent scope in them. They have to be explicitly passed down, either through the router or through the bindings.
For more information, you should take a look at the Component Router section of the Angular developer guide - the documentation for the new router is really sparse, but that guide does a good job of explaining how it all works.

ngRoute RouteController getting called only once

I've a fiddler to show my setup.
http://jsfiddle.net/smartdev101/dt6kkyy3
The problem is the routeController function is getting called only once on the page load, but then on hash change (as a result of link click), the function routeController is not getting called again.
I've my links generated in another ng module, not sure if the links have to be with in the same module as the router.
<div id="router">
<div ng-view></div>
</div>
<div id="navigation" data-ng-cloak>
<ul id="folios" data-ng-controller="FoliosController" class="nav nav-pills nav-stacked">
<li data-ng-repeat="folio in folios" ng-class="{active: isActive('/search/{{folio.productId}}')}">
{{folio.title}}
</li>
</ul>
<div ui-view></div>
</div>
Edit:
Problem has been further diagnosed. Any list/anchor that was generated by an ng controller, is not responding to hash changes outside the scope, while the static links are. from the plunkr link, "foo" and "bar" clicks trigger the controller but "abc" and "def" are not. please review. Question is how to make "abc" and "def" (dynamic links) respond to changes as well.
http://plnkr.co/edit/ea1OHa?p=preview
The code is behaving as intended with the way you have it coded. You are calling routeController in the constructor of the controller, but its not being invoked anywhere else (the router isn't going to do that either).
If you need the routeController function to be invoked on every route change consider binding to route changing events:
https://docs.angularjs.org/api/ngRoute/service/$route
Take a look at this plunk. Note I am binding to stateChangeSuccess instead since you are using the ui-router instead of ngRoute.
http://plnkr.co/edit/CiYLqnqAzrXoouMSXkuk

Resources