Knockout nested components - javascript

I am trying build components with help of KO component binding, but i have a small problem with nested components.
The scenario is I have text-input component which has a label which also is a component.
<div data-bind="component:{name:'text-input', params:{data:$data, parent:$parent}}," class="form-horizontal">
<div class="form-group row">
<div class="col-sm-1">
<div data-bind="component:{name:'label', params:{}}"></div>
</div>
<div class="col-sm-11">
<input type="text" data-bind="value:value" class="form-control" />
</div>
</div>
</div>
Label component has a JS and a template, template looks like below
<label data-bind="text:labelText"></label>
But I am getting an error Multiple bindings (text and component) are trying to control descendant bindings of the same element
I understand <div class="col-sm-1">element is already bound to text-input context. Now the question is how to achieve this scenario.

The component binding fills the content of the <div> with the component's template, wiping out whatever else might be inside (hence the error). One option would be to add another component binding inside the text-input component's template which would allow a componentName/componentParams to be passed in {componentName: label, componentParams: labelParams}. You could also look at working with component child nodes added in Knockout 3.3.

Actually found the issue. It's kind of silly mistake.
My registered component is label and in my label's template I have <label> HTML tag, but since label is also a component, KO was trying to bind label's template to label tag which resulted in error and recursive loop.

Related

Why the scoped style in vue is useless? The parent element style still affect the child element

The Parent element style:
.container {
margin: 20px;
border:1px solid #f1f1f1;
font-size:14px;
font-weight:normal;
The child element style:
.container{}
But the child element style should be rendered like this:
why there are two data-v-*** in the child element and use the parent container style?
I know it's been ages, but I am going to add something here to help future people.
I encountered the same thing. Basically, I was nesting components within components, and being all fancy with scoped so that each component had a class called .container ... well to my surprise when rendering the styles started conflicting. I thought scoped was meant to fix this...
But apparently by design, that's not the case:
https://vue-loader.vuejs.org/guide/scoped-css.html#mixing-local-and-global-styles
With scoped, the parent component's styles will not leak into child components. However, a child component's root node will be affected by both the parent's scoped CSS and the child's scoped CSS. This is by design so that the parent can style the child root element for layout purposes.
So for instance, I have two components nested, I end up with this:
I have a view loading in two components:
<template>
<div>
<login-splash />
<login-form />
</div>
</template>
The two included are like this:
<template>
<div class="container">
<div>
<h1 class="big">Title</h1>
<h2 class="small">Subtitle</h2>
</div>
</div>
</template>
<template>
<div class="container">
<form class="form">
<label class="label">Username
<input class="input" type="input" name="username">
</label>
<label class="label">Password
<input class="input" type="password" name="password">
</label>
Forgot Password
</form>
<button-submit />
</div>
</template>
The issue is with button-submit which looks like this:
<template>
<div class="container">
<button class="button">Button</button>
</div>
</template>
Each of these files has scoped SCSS and it ends up producing the issue stated above.
This all ladders back to https://v2.vuejs.org/v2/style-guide/#Component-style-scoping-essential
Basically the solution is "use a class naming based solution like bem"... which isn't what anyone wants to hear when they see and use scoped and think it's a silver bullet... I know... but as with all web development, you gotta do what you gotta do.
If you are developing a large project, working with other developers, or sometimes include 3rd-party HTML/CSS (e.g. from Auth0), consistent scoping will ensure that your styles only apply to the components they are meant for.
Beyond the scoped attribute, using unique class names can help ensure that 3rd-party CSS does not apply to your own HTML. For example, many projects use the button, btn, or icon class names, so even if not using a strategy such as BEM, adding an app-specific and/or component-specific prefix (e.g. ButtonClose-icon) can provide some protection.
An alternative is to use CSS Modules, as stated in this answer:
https://stackoverflow.com/a/45900067/1034494
This ends up producing something like this:
There are two data-v attributes because you are specifying a CSS selector in the child component styles. The fact that it's empty does not change that. As long as you don't scope both components' styles, they will of course influence each other, especially if you choose identical class names.

Linking two Vue.js components

I have one single file component that is used to show data and another one that is used to edit the same data. The view has labels and paragraphs where as the edit component has inputs and textareas.
Both of these components take the same data object. Is there a way that by editing the fields (bound with v-model in the edit component) the changes a reflected to the view component?
For example, here's my paragraph.vue that is used to show the data
<template>
<div class="row">
<div class="col-xs-12">
<p>{{ text }}</p>
</div>
</div>
</template>
and here's the edit dialog
<template>
<div class="form-group">
<label for="paragaph-text">Paragraph</label>
<textarea id="paragaph-text" class="form-control" v-model.trim="text"></textarea>
</div>
</template>
If you have multiple components using the same data, you can use a share state as explained in the documentation.
But if the number of components increases, and there are many changes happening, you may need a Centralized State Management like vuex, which is generally preferred in due community.

Angular ng-class not working but regular class attribute works

I have this view template that is a child to another view.
The parent view of this view is a child to the index.html where I am importing my angular and ui-router javascript.
i.e index.html > other view > view below
When I try to change the class = "bubble me" below - which works fine ,to ng-class = "bubble me" my css is not loaded. Am I missing something? The issue is isolated to this view only.
<div class="top"><span>To: <span class="name">{{chat.name}}</span></span></div>
<div class="chat">
<div class="conversation-wrapper">
<div class="conversation-start">
<span>Today, 6:48 AM</span>
</div>
<div class="bubble me" ng-repeat = "message in sent_received">
{{message.msg}}
</div>
<div class="write">
<input ng-model = "input.message" type="text" />
<a ng-click= "sendMsg()" class="write-link send"></a>
</div>
does ng-class work only for conditional classes? I would like to
combine my regular hard coded classes with the conditional ones so I
dont have both a class attribute and an ng-class attribute in my
tags..is there no way of doing this? - in the code above the bubble is
not dynamic. I would like to make the me class only dynamic
This might work for your case.
ng-class="value=='true'?'bubble me':'bubble'"

How do I use a custom DOM node to render to from within a react component

I have the following problem:
I want to write jsx code like
<div className="my-section">
<Window>
<div>Window content</div>
</Window>
</div>
<div className="window-container">
</div>
somewhere in my react content, but I want the window to render in a special DOM element with other windows, something like
<div class="my-section"></div>
<div class="window-container">
<div class="window">
<div>Window Content</div>
</div>
</div>
And to do this transparently I need to tell the component to render to a special DOM node from within the component. Is there a way to do this? If not, how should I accomplish the functionality I am looking for from within React?
You're looking for the special this.props.children list.
When you create a React component instance, you can include additional React components or JavaScript expressions between the opening and closing tags like this:
<Parent><Child /></Parent>
Parent can read its children by accessing the special this.props.children prop.
This will allow you to get the children defined inside your element, then insert them at an arbitrary point for render.
render() {
return (
<div className="window container">
<div className="window">{this.props.children}</div>
<div className="window"></div>
...
</div>
);
}

AngularJS child controller binding

I am including a view using the ngInclude directive. The included view has properties that binds values to $scope.model. This is a problem, since the parent scope is using $scope.model. What i need to do is to "reroute" the included views $scope.model to the parent scope's property $scope.include1.model. How can i do this "scope reroute" the way i want to?
Here is an example showing my problem
<div ng-controller="myCtrl">
<div ng-include="'input.html'"></div>
<div ng-include="'input.html'"></div>
</div>
<script type="text/ng-template" id="input.html">
<div ng-controller="childCtrl">
<input type="text" ng-model="model"/>
</div>
</script>
As you can see i have two includes to the same view, and both input text boxes will be bound to the same value. I want to bind them to different values in myCtrl
I can't make any changes to either my childCtrl or the included view.
You can try this
<div ng-include="'input.html'" ng-init='model=include1.model'></div>
<div ng-include="'input.html'" ng-init='model=include2.model'></div>

Categories

Resources