Reusing HTML: Should I define a state?


#1

I have a little piece of HTML code that visually represents a customer in an ion-list by displaying its name and some other properties:

<div class="customer"><span>{{Name}}</span>.......</div>

I am using it in my customer list page.

Now, I want to use the same HTML to represent a customer in another ionic view (Dashboard).

I wonder about the best practice now to re-use this piece of HTML.

Would it be recommended to define a new state for the template? If yes, how can I embed the template then in a list ('re-use it")? I tried this approach but failed with it, as I did not find out how to embed the template in a ion-list.

Or is there a completely other way recommended?


#2

Yes define a state using same template, you may have also to define another controller due to $ionicView caching.


#3

Thanks for your answer. I do not really understand, I am a newbie to Ionic. I try to paste my code/approach.

I am struggeling about how to use the new state/template in my ion list:

customer.short.html

<div class="customer"><span>{{Name}}</span>.......</div>

app.js:

.state('app.customers', {
    url: '/customers',
    templateUrl: 'templates/customerlist.html',
    controller: 'CustomerCtrl'
  })
 .state('app.customers.short', {
    url: '/customersshort/:Id',
    templateUrl: 'templates/customer.short.html'
  })

customerlist.html

<ion-view view-title="New Customers" ng-controller="CustomerCtrl">  
    <ion-content>   
          <ion-list>
            <ion-item ng-repeat="c in customerlist">
                << how can I use/embed the template "customer.short.html" here? >>
            </ion-item>
         </ion-list> 
      </ion-content>  
</ion-view>

#4

Sorry, I did not understand your question.
This is not an Ionic question, it’s an angular-ui router basic question, you should just read a tutorial on angular ui-router.


#5

OK sorry I was not aware of that.

The angular UI-Router docs say that I should use an “ui-view” tag to be replaced by the child template, so I tried it like below without luck.

I will stick with an Angular UI Router forum then. Sorry for stealing your time.

<ion-view view-title="New Customers" ng-controller="CustomerCtrl">  
    <ion-content>   
          <ion-list>
            <ion-item ng-repeat="c in customerlist">
                <ui-view />
            </ion-item>
         </ion-list> 
      </ion-content>  
</ion-view>

#6

I think to get exactly what you want you don’t need states or uiRouter and just to use the angular directive ng-include.

<ng-include src="path/to/template.html"></ng-include>

states and uiRouter are used for when you want something to happen when someone clicks a URL, not for when you want to re-use bits of html in an ng-repeat.

BTW: I’ve got a course on ionic that you can take if you want, it’s on a special deal for the next 5 days: Early Bird Release of Ionic: From Web To Mobile + Special Offer


#7

Thanks a lot jawache! That tip solves my problem. I was on the wrong way trying to use states for that.

Little correction: When unsing ng-include, it seems that the path to the template expects an expression, so the path needs to be packed into single quotes:

<ng-include src="  'templates/customer.short.html'  "></ng-include>

#8

I think I have a problem with ng-Include in combination with Ionic directives, in my case the OptionButtons of the list (accessed by swiping left) show not up in case I use them inside ng-include:

Working code without ng-include (swiping/option works - buttons show up when swiping):

    <ion-list can-swipe="true">
          <ion-item ng-repeat="c in customerlist">                 
            <div>                
               <span>{{c.Fullname}}</span>
               <ion-option-button class="button-balanced">Upgrade</ion-option-button>
            </div>
          </ion-item>
     </ion-list>

Non working code with ng-include (template is embedded BUT swiping/option does NOT work - no reaction when swiping):

<ion-list can-swipe="true">
      <ion-item ng-repeat="c in customerlist" ng-include=" 'templates/customer.short.html' " >                 
      </ion-item>
 </ion-list>

customer.short.html:

<div>                
     <span>{{c.Fullname}}</span>
     <ion-option-button class="button-balanced">Upgrade</ion-option-button>
</div>

#9

Yes that won’t work, can’t use ng-include and ng-repeat on the same element.

Try with

  <ion-item ng-repeat="c in customerlist"  >
    put ng-include here               
  </ion-item>

#10

jawache, you’re the boss! Thanks!


#11

Why not use it as a directive in this case ? That would be my solution


#12

I’d argue to use existing directives where possible rather than start creating your own, if ng-include does the job then just use it.


#13

I agree with jawache. I think that usage of custom directives makes sense when you need to hide away complex logic behind a single directive (facade pattern).
With simple issues like in my case, the code is more readable using standard directives and tags.

@pmigabreu: What are your pro arguments for using a directive here?


#14

Now that I think of it, it makes sense in this case to be loaded via include instead of a directive because there is no logic specific for this template.
I tend to make directive a instead with this in mind, that at some point it will have some underlying logic (that’s how I can justify my way of thinking)


#15

Generally (not always) my advice with directives and most other things in dev is don’t bother making it re-usable until you use it 3 times, i.e. if this is the 3rd time you are copying and pasting some code then make it re-usable.