16

I have the following code which works for displaying a modal:

app.html

<a click.delegate="setModal('person-information')">Test</a>

<modal>
    <modal-header title.bind="'View Person'"></modal-header>
    <modal-body content.bind="contentModal"></modal-body>
    <modal-footer buttons.bind="['Cancel']"></modal-footer>
</modal>

app.js

setModal(modal) {
    this.contentModal = modal;
    $('.modal').modal();
}

person-information.html

<template>
    <form role="form">
        <div class="form-group">
            <label for="fn">First Name</label>
            <input type="text" value.bind="person.firstName" class="form-control" id="fn" placeholder="first name">
        </div>
        <div class="form-group">
            <label for="ln">Last Name</label>
            <input type="text" value.bind="person.lastName" class="form-control" id="ln" placeholder="last name">
        </div>
    </form>
</template> 

person-information.js

import {bindable, inject} from 'aurelia-framework';

@inject(Element)
export class PersonInformation {  
    constructor() {
        this.person = new Person();
    }
}

class Person{  
    firstName = 'Patrick';
    lastName = 'Bateman';
}

This code works fine for displaying the following:

image of modal dialog

I'm having trouble figuring out how I can inject my own data to dynamically create a "Person".

Pseudocode:

app.html

    <a click.delegate="setModal('person-information', 'Tom', 'Hanks')">Test</a>

app.js

setModal(modal, firstname, lastname) {
    this.contentModal = modal;

    this.contentModal.Person.firstName = firstname;
    this.contentModal.Person.lastName = lastname;

    $('.modal').modal();
}

Has anybody had any experience doing this?

TomSelleck
  • 6,706
  • 22
  • 82
  • 151
  • I don't see anything here that wouldn't work, does `setModal` not get your proper values or what? – PW Kad Dec 24 '15 at 06:40
  • @PWKad When calling the setModal function, I get the following errors in the js console: `Uncaught TypeError: Cannot set property 'firstName' of undefined` And if I try to do: `this.contentModal.person = new Person();` I get: `Uncaught TypeError: Cannot assign to read only property 'person' of person-information` – TomSelleck Jan 04 '16 at 12:36

2 Answers2

6

First, the error is because the contentModal property is simple the string 'person-information' so it does not have defined any person property.

But also there is a problem of concept in your code: You are using content.bind to assign dynamically content to your modal element, so your app.js class do not know about the content and you should not try to assign content property values in your app.js class.

To retain generality you could do something like (not tested)

setModal(modal, props) {
    this.contentModal = modal;
    this.modalProps = props; 
    ...
}

and call it with

<a click.delegate="setModal('person-information', { firstName: 'Tom', secondName: 'Hanks' })">Test</a>

Then in person-information.js do

bind(bindingContext) {        
   this.person.firstName = bindingContext.modalProps['firstName'];
   ....
}

Update:

This solution currently does not work:

DaniCE
  • 2,412
  • 1
  • 19
  • 27
  • That throws the undefined error unfortunately: `Uncaught TypeError: Cannot set property 'firstName' of undefined` – TomSelleck Jan 04 '16 at 15:45
  • I would try debug setModal method to inspect what is the content of this.contentModal and this.contentModal.person. – DaniCE Jan 04 '16 at 15:48
  • yep this.contentModal is just a string which references the `person-information` view-modal. The updated `setModal` method was just pseudocode, it was just to illustrate what I want to happen. – TomSelleck Jan 04 '16 at 16:14
  • I gave your updated answer a try, how can I get `created(...)` to be called, should it happen automatically? – TomSelleck Jan 05 '16 at 08:57
  • "create" it's called as part of the component lifecycle (see http://aurelia.io/docs.html#/aurelia/framework/1.0.0-beta.1.0.7/doc/article/creating-components) – DaniCE Jan 05 '16 at 09:03
  • Oh I see, I've implemented `created(owningView: View, myView: View)` in `person-information.js` but it doesn't seem to be running. I tried `attached()` and it seems to work but not `created(...)` – TomSelleck Jan 05 '16 at 09:48
  • `attached() {console.log("This works!"); }` `created(owningView: View, myView: View) {console.log("This isn't working...");}` – TomSelleck Jan 05 '16 at 09:51
  • I'm really not sure but could you proof with only one parameter: `created(view) {console.log("hope this works...");}` – DaniCE Jan 05 '16 at 09:56
  • 1
    I have tested and the same happens to me, created is not invoked. There is an [open issue about this](https://github.com/aurelia/templating/issues/241). – DaniCE Jan 05 '16 at 10:52
  • Looks like created is working now, last problem seems to be that `owningView.modalProps` is undefined inside created(...) – TomSelleck Jan 11 '16 at 11:14
  • Try call `this.modalProps = props;` before `this.contentModal = modal;` in SetModal method. – DaniCE Jan 11 '16 at 11:47
  • Ok, updated the answer to use `bind()` that passes the parent view-Model (checked). It seems create passes the view not the parent view-model as parameter.. – DaniCE Jan 11 '16 at 12:31
  • In my case bindingContext is: `PersonInformation {parent: PersonInformation, __observers__: Object}` and `modalProps` is undefined.. – TomSelleck Jan 11 '16 at 14:22
1

Change your properties (firstName and lastName) to be writable. writable: true. Something like this:

firstName: {
    value: "Tom",
    writable: true
}

lastName: {
    value: "Hanks",
    writable: true   
}

More info at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties in case it helps.

ProgrammerV5
  • 1,915
  • 2
  • 12
  • 22