0

Currently I am trying to migrate an existing Knockout application to Angular MEAN stack application. In the knockout, the index.html contains this code

<% layout('layout') -%>

<div data-bind="ifnot: id">
    <%- partial('partials/invitation-creating.html') %>
</div>

<div data-bind="if: id">
    <%- partial('partials/invitation-done.html') %>
</div>

How can I achieve this kind of partial html file loading with-in Angular route with single controller (or) multiple controllers. After saving the 'invitation-creating.html' page, I should be able to go to 'invitation-done.html' but url should be the same ( I do NOT want this -> websiteurl/invitation_id)

See that in action http://invitify.azurewebsites.net, when you create an invitation then it will take you to the next page (invitation-done.html) without browser changing it's url. This was achieved in knockout but I want to achieve the same effect in my Angular app too. The Knockout code is here on github for you to see more closely. https://github.com/scriptstar/KOInvitify

What is the best practice to achieve this type of behavior in Angular application.

Please help. Thanks.

Supremestar
  • 190
  • 2
  • 3
  • 11
  • with angular and angular-ui-router you should be able to make similar thing using ui-view and states, I don't really get what is blocking you right now there is many tutorial on the web on how to define your own routing and nest html templates using angular, if there is a part of the code in angular module that you can't get right let me know so I can try to help you – Charlie Nov 05 '14 at 10:05

1 Answers1

6

You can use ng-include for getting the same behavior as partials do: https://docs.angularjs.org/api/ng/directive/ngInclude

In your case:

<div ng-if="!id" ng-include="'partials/invitation-creating.html'">
</div>
<div ng-if="id" ng-include="'partials/invitation-done.html'">
</div>

See this Plunkr for a similar example: http://plnkr.co/edit/nih3JG?p=preview

The suggested approach in Angular however is to define directives, that is, custom tags that not only give you the HTML to include but also bundle the behavior (JavaScript code behind).

I've personally worked with a couple of JavaScript frameworks and partials/includes etc of HTML turned out to be a maintainability nightmare in the long run. They work pretty well to get things done fast, though.
The reason is that normally you want to bind some behavior on your included HTML. Being defined as a partial you probably use that HTML from different places, hence, most probably different "controllers" (or the equivalent in your framework) will act upon them. Thus, making changes to the HTML later in the dev cycle are really, really hard.

The better approach is to create small, autonomous units. Bundle your logic and HTML together and then reuse that unit from within other places in your app. It might seem a slight overhead initially, but it definitely pays off.
(this is also the suggested approach by all serious js frameworks currently out there)

Juri
  • 32,424
  • 20
  • 102
  • 136
  • Thanks for your prompt reply. I have only one control called InvitationCntrl and how can I switch partials while keeping the same controller? Would you please elaborate your approach of ng-include. Thanks. – Supremestar Nov 05 '14 at 10:06
  • @Supremestar I updated my post. You'd have to verify whether you can place the `ng-include` directly on the div itself or within it. – Juri Nov 05 '14 at 10:13
  • Great answer. Really appreciate your help. One final question, shall I be able use the same "MainCtrl" for both the partials? or do I have to create a separate controller for each of the partials? – Supremestar Nov 05 '14 at 10:23
  • As you prefer. You should be able to use it for both as the ng-include (like the partial) will simply paste in the HTML you linked (as if it was already in the page). But as mentioned, the more maintainable approach is to create separate ones, and in that occasion you should definitely take a look at Angular directives. – Juri Nov 05 '14 at 10:26
  • Thanks Juri. Actually I did this before but I was not able to load partials for some reason. I found that you need to put the single quotes inside the double quotes like this.
    – Supremestar Nov 05 '14 at 11:51
  • See this answer @Juri http://stackoverflow.com/a/25903124 do you know why? Thanks for your answer. – Supremestar Nov 05 '14 at 11:59
  • 2
    @Supremestar Oh, yes, sorry, forgot to mention that. I'll correct the it. Well I guess it is because the ng-include directive accepts arbitrary Angular expressions. So if you want Angular to interpret "what you pass it as the param" as string, you have to place quotes around it. Otherwise, the ng-include directive will try to parse it as expression. – Juri Nov 05 '14 at 13:09