最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Materialize CSS Collapsible not expanding - Stack Overflow

programmeradmin3浏览0评论

I'm trying to add an accordion style collapsible with default behavior to my project. The header seems to make it to the UI but it will not expand to show the collapsible-body portion. Any one know how I can make this work? Or see why it isn't?

Here is my html:

<div class="section">
<div ng-repeat="diary in diaries | orderBy:'date' ">
<div class="row">
    <div class="col s2 push-s11">
        <a class="btn-floating btn-large waves-effect waves-light red right-align" ng-click="deleteDiary(diary.id)"><i class="material-icons">delete_forever</i></a>
    </div>
</div>
<div class="row">
    <h5 class="center-align"><b>{{diary.category}}</b></h5> 
    <h6 class="center-align">{{diary.date}}</h6>
</div>

<div class="row">
    <div class="foodContainer">
    </div>
    <div class="row center-align">
        <ul class="collapsible popout" data-collapsible="accordion" watch>
            <li ng-repeat="food in diary.foods">
                <div class="collapsible-header">{{food.title}}</div>
                <div class="collapsible-body">
                        <label><b>Calories: </b><p>{{food.calories}}</p></label>
                        <label><b>Fat: </b><p>{{food.fat}}</p></label>
                        <label><b>Protein: </b><p>{{food.protein}}</p></label>
                        <label><b>Sodium: </b><p>{{food.sodium}}</p></label>
                        <label><b>Sugars: </b><p>{{food.sugars}}</p></label>
                </div>
            </li>
        </ul>
    </div>
</div>
</div>
</div>

Here is the controller where I initialize the collapsible:

"use strict";

app.controller("DiaryCtrl", function($scope, $rootScope, $location, DiaryFactory, FoodFactory){
$scope.selectedDiary = '';
// $scope.selectedDiary = 'Diary0';
$scope.totalCalories = 0;
$scope.totalFat = 0;
$scope.totalProtein = 0;
$scope.totalSodium = 0;
$scope.totalSugars = 0;
$scope.diaries = [];
$scope.foods = [];

//activate materialize collapsible list 
$('.collapsible').collapsible();

//getMeals
//lists all meals on the diary page
let getAllDiaries = function(){
    DiaryFactory.getDiary($rootScope.user.uid).then(function(FbDiaries) {
        $scope.diaries = FbDiaries;
        console.log('diaries: ', $scope.diaries);
        FoodFactory.getFoodsFB($rootScope.user.uid).then(function(FbFoods){
            console.log('foods from controller', FbFoods);
            FbFoods.forEach(function(food){
                $scope.diaries.forEach(function(diary){
                    // console.log('foods', food);
                    if(food.mealId === diary.id){
                        diary.foods = diary.foods || [];
                        diary.foods.push(food);
                        console.log('foods array on diary', diary.foods);
                    }
                });
            });
        });
    });
};
getAllDiaries();

Here is a screenshot: Screen Shot

I'm trying to add an accordion style collapsible with default behavior to my project. The header seems to make it to the UI but it will not expand to show the collapsible-body portion. Any one know how I can make this work? Or see why it isn't?

Here is my html:

<div class="section">
<div ng-repeat="diary in diaries | orderBy:'date' ">
<div class="row">
    <div class="col s2 push-s11">
        <a class="btn-floating btn-large waves-effect waves-light red right-align" ng-click="deleteDiary(diary.id)"><i class="material-icons">delete_forever</i></a>
    </div>
</div>
<div class="row">
    <h5 class="center-align"><b>{{diary.category}}</b></h5> 
    <h6 class="center-align">{{diary.date}}</h6>
</div>

<div class="row">
    <div class="foodContainer">
    </div>
    <div class="row center-align">
        <ul class="collapsible popout" data-collapsible="accordion" watch>
            <li ng-repeat="food in diary.foods">
                <div class="collapsible-header">{{food.title}}</div>
                <div class="collapsible-body">
                        <label><b>Calories: </b><p>{{food.calories}}</p></label>
                        <label><b>Fat: </b><p>{{food.fat}}</p></label>
                        <label><b>Protein: </b><p>{{food.protein}}</p></label>
                        <label><b>Sodium: </b><p>{{food.sodium}}</p></label>
                        <label><b>Sugars: </b><p>{{food.sugars}}</p></label>
                </div>
            </li>
        </ul>
    </div>
</div>
</div>
</div>

Here is the controller where I initialize the collapsible:

"use strict";

app.controller("DiaryCtrl", function($scope, $rootScope, $location, DiaryFactory, FoodFactory){
$scope.selectedDiary = '';
// $scope.selectedDiary = 'Diary0';
$scope.totalCalories = 0;
$scope.totalFat = 0;
$scope.totalProtein = 0;
$scope.totalSodium = 0;
$scope.totalSugars = 0;
$scope.diaries = [];
$scope.foods = [];

//activate materialize collapsible list 
$('.collapsible').collapsible();

//getMeals
//lists all meals on the diary page
let getAllDiaries = function(){
    DiaryFactory.getDiary($rootScope.user.uid).then(function(FbDiaries) {
        $scope.diaries = FbDiaries;
        console.log('diaries: ', $scope.diaries);
        FoodFactory.getFoodsFB($rootScope.user.uid).then(function(FbFoods){
            console.log('foods from controller', FbFoods);
            FbFoods.forEach(function(food){
                $scope.diaries.forEach(function(diary){
                    // console.log('foods', food);
                    if(food.mealId === diary.id){
                        diary.foods = diary.foods || [];
                        diary.foods.push(food);
                        console.log('foods array on diary', diary.foods);
                    }
                });
            });
        });
    });
};
getAllDiaries();

Here is a screenshot: Screen Shot

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Dec 15, 2016 at 1:41 tks2ntks2n 991 silver badge7 bronze badges 1
  • 2 I personally don't use Materialize, but I guess that your problem is this: first, you loads collapsible plugin from materialize and apply those plugin to all .collapsible class, then it load Angular. Since your .collapsible part is generated by Angular LATER, then you must re-apply materialize plugin again after all the .collapsible element have been drawn by Angular. The simplest is using angular-patible plugin, like material.angularjs/latest. It's a mon problem with jQuery based plugin. That's why many develop Angular based plugin – DennyHiu Commented Dec 15, 2016 at 1:56
Add a ment  | 

1 Answer 1

Reset to default 8

I had the same problem with React.js and Materialize CSS before.

The reason is exactly like @DennyHio said, Those DOM are not collapsible because they were created by Angular/React after Materialize CSS finished its initialization scrips.

We have to manually "init" those DOM:

function afterAngularOrReactHasCreatedAllDOM (){
    // Manually make all DOM with .collapsible collapsible 
    $('.collapsible').collapsible();
}
发布评论

评论列表(0)

  1. 暂无评论