angular-ui / ui-router

The de-facto solution to flexible routing with nested views in AngularJS
http://ui-router.github.io/
MIT License
13.53k stars 3k forks source link

States with both `bindings` and `views` properties should not validate #3340

Closed kdbruin closed 7 years ago

kdbruin commented 7 years ago

[Using ui-router v1.0.0-rc1]

I have a 2-factor registration dialog that uses a parent state with two child states. Retrieving the user information in a resolve in the first child state and using a binding to rename the resolve doesn't seem to work.

function userRegistrationConfig($stateProvider, STATES)
{
  $stateProvider
    .state(STATES.REGISTRATION, {
      url: "/registration/:registrationID",
      template: "<div layout-fill ui-view='registration'></div>",
      redirectTo: STATES.REGISTRATION_START
    })

    .state(STATES.REGISTRATION_START, {
      url: "/start",
      views: {
        "registration": "userRegistration"
      },
      params: {
        registrationID: null
      },
      bindings: {
        user: "registrationInfo"
      },
      resolve: {
        registrationInfo: function (registrationService, $transition$)
        {
          return registrationService.getRegistrationInfo($transition$.params().registrationID);
        }
      }
    })

    .state(STATES.REGISTRATION_SMS, {
      url: "/sms",
      views: {
        "registration": "smsVerify"
      },
      params: {
        nextState: null
      }
    });
}

The above doesn't work. When I remove the bindings from the STATES.REGISTRATION_START state and change the registrationInfo to user it all works.

christopherthielen commented 7 years ago

That is supposed to work, so this does look like a bug. Can you reproduce this a plunker for me?

kdbruin commented 7 years ago

I've created a pen for you. As it is now it shows the data. When the "userInfo" to "user" binding is enabled and the "userInfo" resolve is used instead of the "user" resolve the data will not show.

Link to the pen: http://codepen.io/kdbruin/pen/JEQYQX

christopherthielen commented 7 years ago

Hi @kdbruin

I just realized why the problem. http://codepen.io/anon/pen/oZXgwO?editors=0010

bindings is a view property. You should not use the "$default" shorthand view properties (view properties on the state object) when separate views: {} block.

Since your state has a views block and a bindings block, it should not have passed validation. I'll mark this as a bug in the validation code.

You should either do:

state = {
  component: 'user',
  bindings: { user: 'userResolve' },
}

or

state = {
  views: {
    user: {
      component: 'user',
      bindings: { user: 'userResolve' },
    }
  }
}
kdbruin commented 7 years ago

Thanks for the clarification. I will make appropriate changes to my code.