Giter Club home page Giter Club logo

Comments (8)

rjohnson465 avatar rjohnson465 commented on May 18, 2024

Yes, that's because of the scope those functions are being called in -- they are being called from DiagramComponent, not AppComponent, so this.buttonCallback is being evaluated as DiagramComponent.buttonCallback, which of course does not exist. The easiest thing to do here is define your buttonCallback function within your initDiagram function.

from gojs-angular.

anuj9196 avatar anuj9196 commented on May 18, 2024

But then this is limiting the Angular features.

I tried to access data member of the component inside the working button callback method defined in the initDiagram, but again it gives not a function or undefined error. (Updated same stackblitz example)

Use case

There may be cases where I need to use the data members for further actions like storing the received data in a variable to use somewhere else or open a popup modal, etc.

Even the component's members are not accessible from inside the initDiagram.

Also about the 2nd issue, what if I have to calculate the font-size or the margin, etc dynamically and then assign to the go element?

from gojs-angular.

rjohnson465 avatar rjohnson465 commented on May 18, 2024

I see what you're saying. In modern Angular / React, data flow always moves down, from parent to child, so it is unusual to want to reference properties of a parent component (in your case, wanting to reference properties of AppComponent from DiagramComponent, which is where initDiagram is firing).

Generally, all functions you depend on within initDiagram must be defined within initDiagram, as I said before. However, if there is some other data somewhere in your app that those functions must depend on, I recommend you store that in modelData, one of the Input properties DiagramComponent supports. This way, if you change modelData in your app, it will change in DiagramComponent's diagram, so then any function that references that property of modelData will also be effected.

For example, say you want to console.log some property in your app when your buttonCallback fires. Let's call that property 'color.' Change / add that property in your modelData object that you are already binding to your DiagramComponent. In your stackblitz example, you could define it like:

public diagramModelData = { prop: 'value', color: 'red' };

(Also, I see you bound 'familyData' to the [modelData] of your DiagramComponent, you should bind diagramModelData instead)

Then, within initDiagram, define your buttonCallback as something like

function buttonCallback(e, obj) {
console.log(e.diagram.model.modelData.color);
}

If anywhere in your app, you change the value of diagramModelData.color, that change will be reflected in your DiagramComponent's diagram.model.modelData.color, so your callback function will always reflect what your app data is

from gojs-angular.

anuj9196 avatar anuj9196 commented on May 18, 2024

@rjohnson465 Thanks for the explanation. The [modelData] binding was there due to a bug in #1 which prevents rendering of the diagram.

Updated the gojs-angular version and the example as well and the assigned properties to diagramModelData are working fine.

In my case, on click event, I want to open a modal to change the respected value.

constructor(
  private modal: NgbModal
) {}

initDiagram() {
  ...
  click: (e, obj) => {
    this.modal.open(EditNodeComponent, {centered: true});
    this.modal.componentInstance.data = e;
    this.modal.result(res => {
        // res is the updated data, update the same in the family tree
        // also send data in the backend using the service
    }
  }
  ...
}

In the above example, I have to access the modal instance which is binded to the this context. Since this is not accessible from inside the initDiagram method definition, modal and other properties or service instances can not accessed.

May be this issue is related to gojs instead of gojs-angular.

from gojs-angular.

rjohnson465 avatar rjohnson465 commented on May 18, 2024

Again, this is an issue of scope, and how generally, data flow goes from parent to child, not the other way around.

One way to get around this is to set your click handler in your AppComponent's ngAfterViewInit() function. Make sure you have a reference to your DiagramComponent inside your AppComponent (by use of ViewChild) and then do something like

@ViewChild('myDiagram', { static: true }) public myDiagramComponent: DiagramComponent;
public ngAfterViewInit() {
    const appComp: AppComponent = this;
    this.myDiagramComponent.diagram.nodeTemplate.click = function(e, obj) {
      appComp.testLog();
    }
  } // end ngAfterViewInit

  public testLog() {
    console.log("test");
  }

from gojs-angular.

anuj9196 avatar anuj9196 commented on May 18, 2024

Thanks @rjohnson465 It's working this way and this context is also accessible.

Here is what I have done

@ViewChild('myDiag', {static: false}) myDiag: DiagramComponent;

ngAfterViewInit() {
  const $ = go.GraphObject.make;
  const appComp: AppComponent = this;
  this.myDiag.diagram.nodeTemplate.contextMenu = 
    $('ContextMenu', 
      $('ContextMenuButton',
        $(go.TextBlock, 'Working Button'),
        {
          click: (e, obj) => {
            appComp.buttonCallback(e, obj);
          }
        }
      )
    );
  }

buttonCallback(e, obj) {
  console.log('e2: ', e.diagram.model.modelData.color);
  console.log('this object: ', this.name);
}

from gojs-angular.

rjohnson465 avatar rjohnson465 commented on May 18, 2024

That's right, since you're calling appComp.buttonCallback, "this" will refer to AppComponent. Glad it's working for you!

from gojs-angular.

NGabriela avatar NGabriela commented on May 18, 2024

I was able to make it possible to access any property of my enclosing component inside initDiagram by using initDiagram.bind(this).

from gojs-angular.

Related Issues (13)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.