Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular-dart component not always shown in web app

In our Angular-dart application, some components (@NgComponent) are defined. The first time, such a component is shown, it is displayed properly. From the second time on, sometimes the component is shown in the web app, sometimes not. Debugging indicates that, even when not shown, the code of the component is executed. No exceptions/stacktraces seem to occur. When trying to track down the issue, we let the Component implement NgShadowRootAware and we added the method void onShadowRoot(ShadowRoot shadowRoot) {}. Every time a breakpoint is put in the onShadowRoot method, the component is properly shown. When the breakpoint is removed, most of the time the component html is not shown in the web app.

Apparently, resizing (several times) the browser window seems to make the component show up.

view_objectdata_component.dart

library view_objectdata_component;

import 'package:angular/angular.dart';
import 'dart:html';
import '../model/model.dart';


@NgComponent(
    selector: 'view-objectdata',
    cssUrl: '../lib/component/view_objectdata_component.css',
    templateUrl: '../lib/component/view_objectdata_component.html',
    publishAs: 'cmp'
)
class ViewObjectDataComponent implements NgShadowRootAware {

  @NgTwoWay('objectdata-map')
  Map<String, ObjectData> dataMap;  
  @NgTwoWay('readonly')
  bool readonly = true;  

  @NgTwoWay('editLink')
  String theEditLink;  

  String _id;

  ViewObjectDataComponent(RouteProvider routeProvider) {
    _id = routeProvider.parameters['id'];
  }

  bool get hasEditLink => theEditLink != null;
  String get editLink => theEditLink.replaceAll('<id>', _id);

  ObjectData get data  {
    ObjectData val = dataMap[_id];
    return val;
  }

  List<ObjectAttribute> get attributes {
    List<ObjectAttribute> list = [];
    for (ObjectAttribute simAtt in data.attributes.values) {
      list.add(simAtt);
    }
    return list;
  }

  void onShadowRoot(ShadowRoot shadowRoot) {
    shadowRoot.querySelector('#myDiv').children.add(
        new SpanElement()..text = ''
    );
  }
}

view_objectdata_component.html

<div id='myDiv'>
  <h3>{{cmp.data.getAttVal('Name')}}</h3>
    <div><strong>ID: </strong>{{cmp.data.id}}</div>
    <ul>    
      <li ng-repeat="att in cmp.attributes">
         <view-attributevalue objectattribute="att" readonly="cmp.readonly"></view-attributevalue>
      </li>
    </ul>
  <span ng-if="cmp.hasEditLink">    
    <a class="extra-space" href="{{cmp.editLink}}">
      <input type="button" value="Edit">
    </a>
  </span> 
</div>

invoked by:

{{ctrl.changeMainSection('applications')}}
<div>
 <br/>
 <div class="alert alert-info alert-dismissable fade in">         
  <view-objectdata 
    objectdata-map="ctrl.asDataMap(ctrl.applications)" editLink="'#/appComp/<id>/edit'"        
  >   
  </view-objectdata>
  </div>
</div>
like image 228
hbkn Avatar asked Nov 30 '25 02:11

hbkn


1 Answers

I think when your data (applications) gets loaded asynchronically from the queryService this update doesn't trigger the entire chain of dependencies. When you have a breakpoint loading data finishes in the meantime and then all is displayed. If you don't have the breakpoint Angular is done rendering and somehow doesn't recognize the data changes.

There are some patterns in your code that Angular doesn't like that may cause this behavior. (If you upgrade to Angular 0.9.9 you will get some exceptions)

There are several methods where you do things like

  • https://github.com/angular/angular.dart/issues/641
  • https://github.com/angular/angular.dart/issues/633
  • https://github.com/angular/angular.dart/issues/705
  • https://github.com/angular/angular.dart/issues/715

List<ApplicationComponent> get applications creates a new list every time.
String tabClassForMainSection(String section) Angular seems not to like code like this (not sure if this should work) maybe a Bug in Angular (https://github.com/angular/angular.dart/issues/738).
Map<String, ObjectData> asDataMap(List list) { returns a new collection each time it gets called.

Maybe you should consider a different strategy for loading the data. You could inject the QueryService to the component and make an async getApplications method that you call from the component like queryService.getApplications().then((data) => updateApplications(data));

When you take a look at the debug output I posted here https://github.com/angular/angular.dart/issues/738 you see how often Angular calls methods to check for data updates. It is very inefficient if each time a new collection is created. This is the reason why it is not supported in 0.9.9 anymore.

I hope this helps a bit.

like image 153
Günter Zöchbauer Avatar answered Dec 03 '25 20:12

Günter Zöchbauer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!