Search code examples
asp.net-mvcangularjsfamo.usangular-material

Nested modifier ng-repeats do not respect $index?


I've taken a stab at famo.us and angular lately. I like it, but I'm having issues getting my sidenav working the way I want.

Sidenav menu items with sub menu item

When I click any of the Test1-3 menu items, I want child menu items to slide open from beneath them. I have not yet implemented any sliding, as my current problem is that no children seem to respect the fa-index of the layout.

Update: The children load and unload just fine, it's just that they always appear at the bottom of the menu items, rather than beneath them. Am I doing something wrong with the fa-modify tags? If I was working in angular I'm pretty sure my ng-repeats would work as expected with this setup.

                <fa-app>
                    @*<fa-grid-layout fa-options="myGridLayoutOptions">*@
                    <fa-sequential-layout fa-options="navCtrl.sequentialOptions">
                        <fa-modifier ng-repeat="item in admin" fa-size="[true, true]" @*fa-size="[true, undefined]"*@ @*fa-proportions="[1, 1]"*@>
                            <fa-surface>
                                <md-list-item ng-click="navCtrl.toggleMenuExpand($index)" @*ng-click="go(item.link)"*@>
                                    <a>
                                        <md-item-content md-ink-ripple layout="row">
                                            <div class="inset">
                                                <ng-md-icon icon="{{item.icon}}"></ng-md-icon>
                                            </div>
                                            <div class="inset">
                                                {{item.title + " " + $index}}
                                            </div>
                                        </md-item-content>
                                    </a>
                                </md-list-item>
                            </fa-surface>

                            <fa-modifier ng-if="item.active" ng-repeat="submenuItem in item.submenu">
                                <fa-surface fa-index="1">
                                    <md-list-item ng-click="go(submenuItem.link)">
                                        <a>
                                            <md-item-content md-ink-ripple layout="row">
                                                <div class="inset">
                                                    <ng-md-icon icon="{{submenuItem.icon}}"></ng-md-icon>
                                                </div>
                                                <div class="inset">
                                                    {{submenuItem.title + " " + $index}}
                                                </div>
                                            </md-item-content>
                                        </a>
                                    </md-list-item>
                                </fa-surface>
                            </fa-modifier>
                        </fa-modifier>
                    </fa-sequential-layout>
                    @*</fa-grid-layout>*@
                </fa-app>

How would I properly make it so that any children appear correctly underneath each menu item?

Here is the array of each menu item, just to clarify.

var adminmenus = [
{
    link: '/overview',
    title: 'Test1',
    icon: 'settings',
    active: true,
    submenu: [{ link: '/overview', title: 'Test1SubTest1', icon: 'settings', active: false }]
},
{
    link: '/overview',
    title: 'Test2',
    icon: 'settings',
    active: false,
    submenu: [{ link: '/overview', title: 'Test2SubTest1', icon: 'settings', active: false }]
},
{
    link: '/handover',
    title: 'Test3',
    icon: 'attach_money',
    active: false,
    submenu: [{ link: '/overview', title: 'Test3SubTest1', icon: 'settings', active: false }]
}
];

Update: Am I perhaps looking at the famo.us implementation in the wrong way? I saw this answer, wondering if I should generate the menu with the appropriate sub menus from the controller instead..


Solution

  • So long story short, this feature is most likely not implemented in the famous/angular integration, simply.

    I am leaving this attempt due to that famo.us is doing a major rework of their engine, whereas famous/angular is left in the dust. For anyone reading, I advise looking into famo.us and angular again in a year when their new engine has been developed on well enough.

    This (somewhat hidden) announcement is from Zack Brown from famo.us.

    The future of Famo.us/Angular

    I can give some insight in the future of Famous in relation to AngularJS, and the path we've taken to arriving at this decision.

    Famo.us/Angular is an integration library. Its roots extend deeply into both of the integrated libraries (Famo.us 0.3 and Angular 1.x) and its implementation is very specific to the idiosyncrasies of those two libraries. Some example integrations:

    patching into Angular's animation and lifecycle system to trigger and handle Famo.us animations patching into Angular's directive compilation system to build the Famo.us render tree in the first place creating directives that allow Famo.us event piping into the underlying Famo.us render nodes supporting Angular's event pipeline (e.g. ng-click on top of Famo.us Surfaces) supporting ng-repeating elements into a Famo.us Scrollview or GridLayout handling cases like ng-show and ng-if in Famo.us making the whole thing perform well within the constraints of Angular's digest cycle. etc. And these are just a few of the many adventures that we encountered while building Famo.us/Angular. Now let's bring four different libraries into the mix:

    Famo.us 0.3 Famous Engine, a.k.a. "mixed mode," a.k.a. 0.5.0 Angular 1.x Angular 2 To fully support integrations between {Famo.us 0.3, Famous Engine}x{Angular 1.x, Angular 2} would require four completely distinct integration libraries. Obviously, this isn't tenable.

    Famo.us 0.3 is deprecated. Thus, we can rule out integrating it with Angular 2. The question then becomes: should we write an integration between Engine and Angular 1.x, or Engine and Angular 2, or both? While we're at it, should we build an integration with React? With Ember? With Backbone? Mithril? FOAM? Insert-JavaScript-Framework-Du-Jour?

    The answer is, we absolutely plan to support all of these, but we don't want to (and can't afford to) write a from-the-ground-up integration with all of them.

    So what's the trick?

    If we do our job right, no one will have to write a heavy-weight integration like this again.

    We (at Famous) have to write "one integration to support them all" — we don't want to integrate Famous Engine with AngularJS; we want to integrate Famous Engine with web authoring standards in such a way that using Famous with, say, Angular or React—or even just Bootstrap—is simple. The good news: we're already writing it. It's our Framework Layer. (oh, and that's why Engine is called Engine—it's one of two layers of the Famous Project: Engine and Framework.)

    What does this Framework look like?

    It supports HTML as an authoring language. This is key, as it allows mixing in other applications/frameworks both inside and outside of the Famous render tree.

    It exposes very clear, simple-to-use interfaces for manipulating Famous components. This allows for logic from any other application/framework to interact with Famous in a consistent, predictable, and extensible way.

    It supports passing through to raw Famous Engine anywhere it's needed.

    It supports passing into and out of Famous or HTML flexibly, and allows easily working with CSS and other assets (images, fonts, other media.)

    In other words: writing an Angular integration with the Framework will be loads simpler than writing it with straight-up Engine. I strongly encourage anyone who's interested in an Angular<>Famous integration to wait for the rest of Famous, i.e. the Framework, to be released.

    When is that?

    As of now (June 2015) Framework is still in Private Beta. We are inviting anyone who's interested and who can make it to come on site in SF to work with us in Famous Labs to test-drive the Framework and get/give feedback directly with the Framework team.

    We will be making an announcement about Framework at jQuerySF toward the end of June. It's very possible we will release our Public Beta on that date.

    You can reach me at [email protected] if you're interested in the Private Beta or more information.