Here I have a complex data structure in an Angular4 application.
It is a directed multigraph parametrized with dictionaries both on nodes and on links. My angular components are working on this complex data model.
In Angular2.4, everything worked fine. Since we switched to Angular4, I get this into my DOM:
<g flareNode="" ng-reflect-model="{'id':'an-id-of-my-object'">
...which is generated from the following template snippet:
<svg:g flareNode [model]="item"></svg:g>
Note, model
is here simply a data member of my component. It has no (...should have no) specific Angular2 meaning. It is a part of the complex data structure behind my app.
My first impression is that Angular serializes the model
data member of the component class, gets its 30 first characters, and then puts this totally useless thingy into the DOM!
Am I right? What is this whole ng-reflect-model
in the DOM, what specific purpose has it in Angular4 what it didn't have in Angular2?
ng-reflect-model
attribute is for, and maybe that what could be the reason of this strange behavior (putting the first 30 characters of an object into the DOM as the value of an attribute). Any answer explaining what is the role of the ng-reflect-model
inside the Angular framework is already acceptable.
ng-reflect
attributes added to my components, but they were added in 2.4. If you create a plunker with DOM with such attributes, I'll take a look
ng-reflect
is used. IMHO, there is no one on stackoverflow who can answer that question right now. I'm interesting to make some debugging and find the answer, as I write in-depth articles, but I need a demo. I spent an hour today trying to come up with an example, but couldn't get ng-reflect
to be added.
ng-reflect-${name}
attributes are added for debugging purposes and show the input bindings that a component/directive has declared in its class. So if your component is declared like this:
class AComponent {
@Input() data;
@Input() model;
}
the resulting html will be rendered like this:
<a-component ng-reflect-data="..." ng-reflect-model="...">
...
<a-component>
They exist only when debugging mode is used - default mode for Angular. To disable them, use
import {enableProdMode} from '@angular/core';
enableProdMode();
inside main.ts
file. These attributes are added by this function here:
function debugCheckAndUpdateNode(...): void {
const changed = (<any>checkAndUpdateNode)(view, nodeDef, argStyle, ...givenValues);
if (changed) {
const values = argStyle === ArgumentType.Dynamic ? givenValues[0] : givenValues;
if (nodeDef.flags & NodeFlags.TypeDirective) {
const bindingValues: {[key: string]: string} = {};
for (let i = 0; i < nodeDef.bindings.length; i++) {
const binding = nodeDef.bindings[i];
const value = values[i];
if (binding.flags & BindingFlags.TypeProperty) {
bindingValues[normalizeDebugBindingName(binding.nonMinifiedName !)] =
normalizeDebugBindingValue(value); <------------------
}
}
...
for (let attr in bindingValues) {
const value = bindingValues[attr];
if (value != null) {
view.renderer.setAttribute(el, attr, value); <-----------------
Success story sharing
ng-reflect-model="[object Object]"
. How to get knowledge what object it is?[object Object]
because Angular callstoString()
on an object. You should know what object it is by inspecting input bindings.ng.probe
like thisng.probe($0).componentInstance[inputBindingProperty]